这种语法是非法的吗?

Is this syntax illegal?

以下不会在 GCC 4.8.1 上编译:

//struct Tag {};  // Program compiles if I use this.

template <typename T>
struct Base {
    struct Tag {};
    Base(Tag) {}
};

template <typename T>
struct Derived : Base<T> {
    Derived(Tag tag) : Base<T>(tag) {}
//  Derived(Base<T>::Tag tag) : Base<T>(tag) {}
};

int main() {}

抱怨 [错误] 在 'tag' 之前应为 ')'。它在 Visual Studio 2013 上编译,我想知道 VS2013 是否正确接受它。当我在 Base<T> 之外声明 Tag 时它确实编译,但我想在它所属的 Base<T> 内部声明 Tag。使用 Derived(Base<T>::Tag tag) : Base<T>(tag) {} 也没有帮助。解决上述问题的任何方法,以便两个编译器都接受它,同时将 Tag 保留在 Base<T>.

[temp.dep]/3:

In the definition of a class or class template, if a base class depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.

Tag 用作非限定名称 - 因此它永远不能指定依赖基 class 的成员。但是,Tag 也不依赖,因此必须在定义时(在实例化之前)解析查找,这使得程序格式错误。这可以在定义或实例化时诊断。

但是,当名称依赖时(如 Base<T>::Tag),名称查找将被推迟并在实例化时考虑依赖基 classes 的成员。