嵌套 类 中 g++ 和 clang++ 之间的不同行为
Different behavior between g++ and clang++ in nested classes
我注意到 gcc
9.2.0 和 clang++
9.0.1 之间存在不同的行为。我的代码如下
//header.hh
...
template <typename T>
class Outer {
...
public:
template <typename S>
class Inner;
...
};
template <typename T>
template <typename S>
class Inner {
...
Inner& func();
...
};
那么,由于函数func()
是在另一个文件中实现的
//implementation.cc
template <typename T>
template <typename S>
Outer<T>::Inner<S>& Outer<T>::Inner<S>::func() {
...
};
现在,如果我使用 g++
编译就可以了。如果我使用 clang++
我得到
src/implementation.cc:6:1: error: missing 'typename' prior to dependent type template name 'Outer<T>::Inner'
Outer<T>::Inner<S>& Outer<T>::Inner<S>::func() {
^
1 error generated.
但是如果我按照它的建议使用
typename Outer<T>::Inner<S>& Outer<T>::Inner<S>::func()
我遇到另一个错误:
src/implementation.cc:6:21: error: use 'template' keyword to treat 'Inner' as
a dependent template name typename Outer<T>::Inner<S>& Outer<T>
::Inner<S>::func() {
而且现在它的建议看起来很奇怪
问题
- 为什么两个编译器的行为不同?
- 正确的语法是什么?
正确的语法如下:
template <typename T>
template <typename S>
typename Outer<T>::template Inner<S> &Outer<T>::Inner<S>::func() {
...
}
您可以在 this 问题中找到此语法的完整解释。
但是,更简单且有效的语法是:
template <typename T>
template <typename S>
auto Outer<T>::Inner<S>::func() -> Inner& {
...
}
通过在上面的示例中使用尾随的 return 类型语法,您可以利用名称解析范围在 Outer<T>::Inner<S>
内的事实,因此您可以使用 injected class name Inner
.
我注意到 gcc
9.2.0 和 clang++
9.0.1 之间存在不同的行为。我的代码如下
//header.hh
...
template <typename T>
class Outer {
...
public:
template <typename S>
class Inner;
...
};
template <typename T>
template <typename S>
class Inner {
...
Inner& func();
...
};
那么,由于函数func()
是在另一个文件中实现的
//implementation.cc
template <typename T>
template <typename S>
Outer<T>::Inner<S>& Outer<T>::Inner<S>::func() {
...
};
现在,如果我使用 g++
编译就可以了。如果我使用 clang++
我得到
src/implementation.cc:6:1: error: missing 'typename' prior to dependent type template name 'Outer<T>::Inner'
Outer<T>::Inner<S>& Outer<T>::Inner<S>::func() {
^
1 error generated.
但是如果我按照它的建议使用
typename Outer<T>::Inner<S>& Outer<T>::Inner<S>::func()
我遇到另一个错误:
src/implementation.cc:6:21: error: use 'template' keyword to treat 'Inner' as
a dependent template name typename Outer<T>::Inner<S>& Outer<T>
::Inner<S>::func() {
而且现在它的建议看起来很奇怪
问题
- 为什么两个编译器的行为不同?
- 正确的语法是什么?
正确的语法如下:
template <typename T>
template <typename S>
typename Outer<T>::template Inner<S> &Outer<T>::Inner<S>::func() {
...
}
您可以在 this 问题中找到此语法的完整解释。
但是,更简单且有效的语法是:
template <typename T>
template <typename S>
auto Outer<T>::Inner<S>::func() -> Inner& {
...
}
通过在上面的示例中使用尾随的 return 类型语法,您可以利用名称解析范围在 Outer<T>::Inner<S>
内的事实,因此您可以使用 injected class name Inner
.