Scope resolution for template instantiation
Asked Answered
X

1

6

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?

Xanthine answered 22/11, 2011 at 12:39 Comment(3)
that's interesting. apparently, the namespace usings work lexically while instantiating the template. That's surprisingHypermeter
FWIW: g++ 4.5.3 agrees that it should not have been a problemHypermeter
@sehe: it's not a problem (Standard-wise), but MSVC is not Standard compliant with regard to templates... (not even in the latest version)Jollanta
J
7

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.

Jollanta answered 22/11, 2011 at 13:10 Comment(5)
@sehe: To be honest, I find it quite sad that such a big product would not aim for more compliance. I guess it stems from VC++ overwhelming position on the Windows market: they don't care to do better because they have no concurrence, and thus no incentive.Jollanta
no concurrence -> no competition? O, and I concur. See also VC++ Team Blog on C++11Hypermeter
@MatthieuM. Thanks - good to know what's going on, but sad to know that even moving to more recent MSVC won't help! (I see no prospect of my organisation moving away from the MSVC environment unfortunately.) Could you suggest a reference I could link to for future readers of my code? Otherwise I will use a permalink to your answer here ;-)Xanthine
@sehe: thanks for the link, I had not followed the latest moves and it's illuminating indeed. Too bad when they have Herb Sutter in such a high position at both MS and the C++ committee that C++ would end up a second zone citizen :(Jollanta
@MatthieuM. off-topic, but a page well worth all your votes: Visual Studio UservoiceHypermeter

© 2022 - 2024 — McMap. All rights reserved.