A private membership test using metaprograms, GCC vs clang, what is true?

This is a question about the C ++ standard. Consider the following code:

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) {}

The above code works with gcc (GCC) 4.4.3

However with clang version 3.3 (2545b1d99942080bac4a74cda92c620123d0d6e9) (2ff97832e593926ea8dbdd5fc5bcf367475638a9)

he gives this error:

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.

Which one is right?

From a standard document ( n3485 ), I found an expression that seems to be more consistent with clang than gcc.

Access control applies evenly to all names, regardless of whether the names refer to declarations or expressions.

+5
source share
1 answer

I would suggest that the GCC is right.

, friend . , , , . - , ( ) . .

SFINAE: . MyClass::Data , has_Data - - - , C::Data. , , , . , GCC 4.7.2 has_Data<MyClass>::value false. SFINAE, .

, , 14.8.2 8

. .

, , -, , SFINAE , GCC.

: @hvd , C + +11. . 1170: .

GCC -std=c++03 -std=c++11 - , typeof GNU. , -std=gnu++03 , , , ++ 11, .

+3

All Articles