Разрешение области действия для создания шаблона - PullRequest
6 голосов
/ 22 ноября 2011

У меня есть следующий набор классов (минимальная репликация моей реальной ситуации):

namespace Parent
{
  class A {};

  namespace Nested
  {
    class A {};
  }

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

Я ожидаю, что член Parent::B::myA должен быть однозначно разрешен как тип Parent::A.Тем не менее, в другом месте в моем проекте у меня есть это:

namespace Parent
{
  using namespace Nested;

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

, который не удается скомпилировать в 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 ]

Код будет компилироваться, если я явно в моем объявлении B::myA, т.е. Parent::A myA;.Тем не менее, код компилируется, как в gcc-4.3.4 .Это просто ошибка в MSVC 2003, или мне действительно нужно беспокоиться о том, в какой области могут создаваться мои шаблоны?

1 Ответ

6 голосов
/ 22 ноября 2011

Это давняя ошибка во всех версиях MSVC.

Проблема связана с неправильной реализацией поиска имени в шаблонах в MSVC.

По сути, MSVC будет ждать, покаточка инстанции для выполнения поиска по имени, в то время как Стандарт явно указывает, что правильное поведение заключается в следующем:

  • немедленно выполнить поиск по имени (в точке объявления) для независимых символов
  • выполнить поиск имени при создании экземпляра для зависимых символов

Такое поведение позволяет MSVC быть слабым в отношении использования typename или template, потому что он может полностью определить природу символов (дифференцировать обычные переменныеиз функций или типов), однако это кошмар, когда кто-то стремится к совместимости с другими компиляторами.

Если вы можете, угробите MSVC.Если ты не можешь ... удачи.

...