以下内容无法在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是否正确接受它。当我在Tag
之外声明Base<T>
时,它会编译,但我想在Tag
内声明它所属的Base<T>
。使用Derived(Base<T>::Tag tag) : Base<T>(tag) {}
也无济于事。任何方法可以解决上述问题,以便两个编译器都接受这一点,同时将Tag
保留在Base<T>
内。
答案 0 :(得分:3)
[temp.dep] / 3:
在类或类模板的定义中,如果是基类 取决于模板参数,不检查基类范围 在非限定名称查找期间或者在定义时 类模板或成员或在类的实例化期间 模板或成员。
Tag
用作非限定名称 - 因此它永远不能指定依赖基类的成员。但是,Tag
也不依赖,因此必须在定义时(实例化之前)解析查找,这会使程序格式错误。这可以在定义或实例化时间进行诊断。
但是,当名称依赖时(如Base<T>::Tag
),名称查找将被推迟并在实例化时考虑依赖基类的成员。