Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template argument name collision with method in MSVC C++

Tags:

c++

visual-c++

Following snippet does not compile in MSVC C++ (2015, 2017):

template <typename Type>
struct Base : public Type
{
    Base(const Type & type)
    : Type(type)
    {}
};

struct SomeType
{
    int Type() { return 42; }
};

struct Wrong : public Base<SomeType>
{
    Wrong(const SomeType & type)
    : Base<SomeType>(type)
    {}
};

SomeType some;
Wrong wrong(some);

The compiler is confused and interprets calling the Type constructor with a call to Type() method of class I try to derive from. GNU C++ compiler has no problem with the code.

Renaming the template argument Type in the Base class declaration to something different (not in collision with any method of base class) solves the problem. Adding something like : (typename Type)(type) does not help.

Is this a bug of MSVC C++ compiler. Any tips for resolving these kind of problems?

like image 774
Freemanix Avatar asked Oct 10 '17 08:10

Freemanix


1 Answers

This is a bug in MSVC++. Two-phase lookup requires Type to be resolved as the name of the template parameter, and a base, during the template definition!

The fact there is such a member at the point of instantiation should not interfere. When templates are implemented correctly, it doesn't, as you noted with GCC.

But Microsoft didn't implement it correctly until recently. In their implementation, a template behaves more like a macro, which is the cause of error.

like image 69
StoryTeller - Unslander Monica Avatar answered Oct 18 '22 11:10

StoryTeller - Unslander Monica