Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scope resolution for template instantiation

I have the following set of classes (a minimal replication of my real situation):

namespace Parent
{
  class A {};

  namespace Nested
  {
    class A {};
  }

  template <typename T>
  class B
  {
    A myA;
  };
}

I would expect that the member Parent::B::myA should be unambiguously resolved to be of type Parent::A. However, elsewhere in my project I have this:

namespace Parent
{
  using namespace Nested;

  void foo()
  {
    B<int> myB;
  }
}

which fails to compile under MSVC 2003:

error C2872: 'A' : ambiguous symbol
        could be 'Test.cpp(5) : Parent::A'
        or       'Test.cpp(9) : Parent::Nested::A'
        Test.cpp(26) : see reference to class template instantiation 'Parent::B<T>' being compiled
        with [ T=int ]

The code will compile if I am explicit in my declaration of B::myA, i.e. Parent::A myA;. However, the code compiles as it is under gcc-4.3.4. Is this simply a bug with MSVC 2003, or should I really have to worry about the scope in which my templates may be instantiated?

like image 559
atkins Avatar asked Nov 22 '11 12:11

atkins


People also ask

What is the instantiation of the class template?

The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation.

How do I instantiate a template?

To instantiate a template class explicitly, follow the template keyword by a declaration (not definition) for the class, with the class identifier followed by the template arguments. template class Array<char>; template class String<19>; When you explicitly instantiate a class, all of its members are also instantiated.

Is it necessary to instantiate a template?

Class template instantiationIn order for any code to appear, a template must be instantiated: the template arguments must be provided so that the compiler can generate an actual class (or function, from a function template).

Are templates resolved at compile time?

All the template parameters are fixed+known at compile-time. If there are compiler errors due to template instantiation, they must be caught at compile-time!


1 Answers

It is a long standing bug in all versions of MSVC.

The problem is related to an incorrect implementation of name lookup in templates in MSVC.

Basically, MSVC will wait until the point of instantiation to perform name lookup, while the Standard is explicit that the correct behavior is to:

  • perform name lookup immediately (at the point of declaration) for non dependent symbols
  • perform name lookup at instantiation for dependent symbols

This behavior allows MSVC to be lax with regard to the use of typename or template, because it can fully deduce the symbols nature (differentiate regular variables from functions or types), however it's a nightmare when one aims at compatibility with other compilers.

If you can, ditch MSVC. If you can't... good luck.

like image 82
Matthieu M. Avatar answered Sep 27 '22 22:09

Matthieu M.