Why does VC ++ 2013 refuse to compile nested types, making the using keyword visible when using template functions as the return type?

Visual Studio 2013 (update 2) generates a compile-time error when compiling the template function, the type of the return type is the nested type name that was hidden through multiple inheritance and became visible again with the using keyword; as in the following code:

 struct Base1 { typedef int value_type; }; struct Base2 { typedef double value_type; }; struct Derived : Base1, Base2 { using Base1::value_type; }; template<typename T> typename T::value_type nullary_function() { return 0; } template<typename T> typename T::value_type unary_function(T t) { return 0; } int main() { nullary_function<Derived>(); // Error: C2770 unary_function( Derived() ); // Error: C2893 return 0; } 

(The error numbers vary depending on whether the function accepts template arguments or not, as shown in the comments.)

g ++ 4.7 accepts this code.

In particular, I would like to know what the C ++ standard has to say on this issue and whether this is a VC ++ compiler error. (It seems to me that he sees that the nested types visible with the using keyword make them visible in any other situation, as far as I know).

I also know that the line with the using keyword can be changed from

 using Base1::value_type; 

to

 typedef Base1::value_type value_type; 

to get the code to compile and work correctly, but for portability for some (potentially) valid code to compile some compilers and not others, this seems bad. Hence the desire for clarification.

+7
c ++ multiple-inheritance visual-studio-2013 templates nested
source share
1 answer

This is really a compiler error - ICC, CLang and g ++ accept this code as verified by Godbolt .

The most appropriate language in the standard that I could find is 7.3.3 (namespace.udecl) p2 (quoted from N3337 )

Each declaration of use is a declaration and declaration of a member and therefore can be used in the definition of a class.

PS ICC, CLang, and g ++ all also accept the typedef version.

0
source share

All Articles