此语法是否非法

Is this syntax illegal?

本文关键字:非法 是否 语法      更新时间:2023-10-16

以下内容将无法在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() {}

抱怨 [错误] 在"标记"之前应为")"。 不过,它是在Visual Studio 2013上编译的,我想知道VS2013接受它是否正确。 当我在Base<T>之外声明Tag时,它确实会编译,但我想在它所属的Base<T>内部声明Tag。 使用Derived(Base<T>::Tag tag) : Base<T>(tag) {}也无济于事。 修复上述问题的任何方法,以便两个编译器都接受这一点,同时Tag保留在Base<T> .

[temp.dep]/3:

在类或类模板的定义中,如果基类 取决于模板参数,不检查基类范围 在非限定名称查找期间,或者在定义 类模板或成员,或在类实例化期间 模板或成员。

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

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