Home Dashboard Directory Help
Search

Base class hides template parameter with the same name. by Cassio Neri


Status: 

Closed
 as Deferred Help for as Deferred


1
0
Sign in
to vote
Type: Bug
ID: 778865
Opened: 2/8/2013 2:27:18 PM
Access Restriction: Public
2
Workaround(s)
view
0
User(s) can reproduce this bug

Description

It's commom for a template classe to derive from one of its parameters. For instance,

ctemplate <typename Base>
struct Foo : public Base {
Foo() { Base::f(); }
};

There is an issue when this template is instantiated for a class that has a base with the same name as the template parameter, i.e., Base. In this case, inside Foo's scope the base class hides the template parameter and apparently there's no way to refer to the class used in the instantiation.

The code in the section "Steps to reproduce" show an example. VS 2010, VS2012 and VS CTP Nov 2012 output "Bad" whereas GCC 4.6.3, GCC 4.7.2, GCC 4.8.0, Clang 3.2 and Intel 13.0.1 ouptut "Good". This is a simple example where the code compiles but produces a wrong output. In other variations of this issue the code might fail to compile in Visual Studio.
Details
Sign in to post a comment.
Posted by Cassio Neri on 8/10/2013 at 7:15 AM
This bug is still present in Visual Studio 2013 preview.
Posted by Microsoft on 2/10/2013 at 6:26 PM
Thanks for your feedback.

We are rerouting this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.
Posted by Microsoft on 2/8/2013 at 2:50 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.
Posted by Cassio Neri on 2/8/2013 at 2:43 PM
This workaround does not suffer the issue on the extra parameter misuse mentioned in the previous one.

template <typename T>
struct MakeAlias {
typedef T Alias;
};

template <typename Base>
struct Foo : public MakeAlias<Base>, public Base {
typedef typename Foo::Alias Alias;
Foo() { Alias::f(); }
};

Actually, Visual Studio does not require the line "typedef typename Foo::Alias Alias;" (I believe, it should). However, this line doesn't harm Visual Studio and is compulsory for the other compilers. So adding this line improves portability.
Posted by Cassio Neri on 2/8/2013 at 2:33 PM
The key is "saving" the parameter name before entering in Foo's scope (i.e., inside the curly brackets {}).

template <typename Base, typename Alias = Base>
struct Foo : public Base {
Foo() { Alias::f(); }
};

The problem with this workaround is that clients might misuse the extra parameter.