Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top