Template argument name resolution and compiler discrepancies

96 views
Skip to first unread message

Jonathan Jones

unread,
Sep 12, 2015, 12:30:07 PM9/12/15
to

Hi folks,

Look at the following example code:

template<typename>
class Base
{
typedef int ValueType;
};

template<typename ValueType>
struct Derived : public Base<ValueType>
{
Derived(ValueType);
};

Derived<float> obj(1);

This code compiles cleanly with GCC 4.7.2 and Clang 3.5 (Xcode 6.2).
However, it fails to compile with Visual Studio 2013, complaining that it
cannot access private typedef "Base<ValueType>::ValueType".

Furthermore, if you make the private typedef public:

template<typename>
class Base
{
public:
typedef int ValueType;
};

It compiles on all three compilers, but the produces different answers.
GCC and clang result in ValueType=float in the Derived constructor
definition, whereas Visual Studio 2013 results in ValueType=int in the
Derived constructor definition.

What does the standard say should happen in these cases? Which compiler(s)
are closer to implementing the standard behavior?

The standard is clear (see C++11 section 14.6.1 paragraph 9) about what
happens when "Base" is not a template, but it seems more vague about when
"Base" is a template (which the example above seems to demonstrate).

Sincerely,
Jonathan Jones


--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp...@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Bo Persson

unread,
Sep 13, 2015, 9:00:11 AM9/13/15
to
I would use different names when Base::ValueType is not the same as
Derived::ValueType. :-)


Otherwise, I suspect this is one symptom of VC++ failing to do a proper
2-phase name lookup. When Base is a template, its ValueType should not be
visible in the declaration of Derived(ValueType). If VC++ postpones the
name lookup until the template is instantiated, it WILL be visible at that
point.

However, as you say, when Base is not a template its ValueType will shadow
the template parameter in Derived. That's one reason for using a different
name.


Bo Persson
Reply all
Reply to author
Forward
0 new messages