Это скорее вопрос стандартов C ++. Рассмотрим следующий код:
template <typename T>
class has_Data
{
typedef char one;
typedef long two;
template <typename C> static one test( typeof(&C::Data) ) ;
template <typename C> static two test(...);
public:
enum { value = sizeof(test<T>(0)) == sizeof(char) };
};
class MyClass {
private:
struct Data {
};
};
void function(bool val = has_Data<MyClass>::value) {}
Приведенный выше код работает с gcc (GCC) 4.4.3
Однако с clang version 3.3 (2545b1d99942080bac4a74cda92c620123d0d6e9) (2ff97832e593926ea8dbdd5fc5bcf367475638a9)
это дает эту ошибку:
test_private_data.cpp:7:54: error: 'Data' is a private member of 'MyClass'
template <typename C> static one test( typeof(&C::Data) ) ;
^
/devshared/home/rhanda/test_private_data.cpp:7:37: note: while substituting explicitly-specified template arguments into function template 'test'
template <typename C> static one test( typeof(&C::Data) ) ;
^
/devshared/home/rhanda/test_private_data.cpp:21:26: note: in instantiation of template class 'has_Data<MyClass>' requested here
void function(bool val = has_Data<MyClass>::value) {}
^
1 error generated.
Какой из них правильный?
Из стандартного документа (n3485), Я нашел утверждение, которое, похоже, больше согласуется с clang, чем с gcc.
Контроль доступа применяется единообразно ко всем именам, независимо от того, упоминаются ли имена из объявлений или выражений.
template <typename C> static one test( typename C::Data * );
? Мне просто любопытно, чтоdecltype( &C::Data )
делает для вас ... - person lapk   schedule 25.04.2013decltype( &C::Data )
неtype of pointer to a data-member C::Data
? Потому что, если вы запустите свой тест, как показано, параметрfunction()
val
будет0
. Разве вы не имеете в виду, что это будет1
дляMyClass
? - person lapk   schedule 25.04.2013typeof
не является частью стандарта C ++, это расширение GCC. - person NonNumeric   schedule 25.04.2013