1

以下内容无法在 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' 之前抱怨 [Error] 预期的 ')'。虽然它在 Visual Studio 2013 上编译,但我想知道 VS2013 是否正确接受它。Tag当我在外部声明时它会编译Base<T>,但我想在它所属Tag的地方声明。Base<T>使用Derived(Base<T>::Tag tag) : Base<T>(tag) {}也没有帮助。解决上述问题的任何方法,以便两个编译器都接受这一点,同时保留TagBase<T>.

4

1 回答 1

3

[温度.dep]/3:

在类或类模板的定义中,如果基类依赖于模板参数,则在非限定名称查找期间,无论是在类模板或成员的定义点还是在类模板或成员的实例化期间,都不会检查基类范围类模板或成员。

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

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

于 2015-01-11T15:48:08.163 回答