C++ 这种语法违法吗?

C++ 这种语法违法吗?,c++,templates,language-lawyer,name-lookup,C++,Templates,Language Lawyer,Name Lookup,以下内容不适用于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&g

以下内容不适用于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() {}
//结构标记{};//如果我使用这个,程序就会编译。
模板
结构基{
结构标记{};
基(标记){}
};
模板
派生结构:基{
派生(标记):基(标记){}
//派生的(Base::Tag Tag):Base(Tag){}
};
int main(){}
“tag”之前应为“)”而不是“Error”。不过它是在Visual Studio 2013上编译的,我想知道VS2013接受它是否正确。当我在
Base
外部声明
Tag
时,它会编译,但我想在
Base
内部声明
Tag
它所属的位置。使用
Derived(Base::Tag-Tag):Base(Tag){}
也没有帮助。修复上述问题的任何方法,以便两个编译器都接受此选项,同时将
标记保持在
Base
内部[temp.dep]/3:

在类或类模板的定义中,如果是基类 根据模板参数,不检查基类范围 在非限定名称查找期间在 类模板或成员,或在类的实例化过程中 模板或成员

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


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

您的代码在Visual Studio中编译得很好。我知道,我已经说过了。但我希望它能在两个编译器上编译。你是说语法是合法的吗?使用
Derived(typename Base::Tag Tag):Base(Tag){}
,因为
Base
是一个从属名称啊,太棒了!非常感谢。问题解决了。但我仍然怀疑原始代码是否合法。