struct A { class Type {}; template < typename Type > ...">

Why doesn't the "external inline" template compile?

So here is the code:

#include <sstream> struct A { class Type {}; template < typename Type > Type as( void ) { std::istringstream test; Type temp; test >> temp; return temp; } }; 

It compiles fine, no problem.

Now here is almost the same code:

 #include <sstream> struct A { class Type {}; template < typename Type > inline Type as(void); }; template < typename Type > Type A::as( void ) { std::istringstream test; Type temp; test >> temp; return temp; } 

Boom, it no longer compiles. Error:

 t.cc:14:10: error: invalid operands to binary expression ('std::istringstream' (aka 'basic_istringstream<char>') and 'A::Type') test >> temp; ~~~~ ^ ~~~~ 

I reproduced this behavior with clang and gcc.

Why do compilers use the wrong type in the second case? (just to be clear: I know there is a conflict with the enumeration, but, in my opinion, the first code also cannot compile if it was a real problem)

+4
source share
1 answer

The scope in A :: as () uses A :: Type as a specifier of type temp. The easiest way to see this is to change the name of the nested class to something other than the type.

The best question is why this happens in the first place. This is due to the declaration point, the search for names and the concealment of names, which are discussed in sections 3.3, 3.4 and 14.6.4 of the standard. This is a rather meaty set of sections, and I will publish specific proposals, since they relate to this problem if / when I get time to narrow them down. So far I rely on 3.3.9-10 and 3.4

In any case, changing the class name allows the template argument to once out of the scope of the structure declaration, the latter being the key to why this happens in the first place (so anyway, I got lucky with the standard).

 struct A { class TypeX {}; template < typename Type > Type as(void); }; template < typename Type > inline Type A::as( void ) { std::istringstream test; Type temp; test >> temp; return temp; } 

I am very sure that if I have the wrong sections of the standard related to this problem, there are enough StackOverflow inhabitants who will send hot rods through this answer.

+3
source

Source: https://habr.com/ru/post/1446604/


All Articles