嵌套类中 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() {
...
}
您可以在此问题中找到此语法的完整解释。
但是,更简单且有效的语法是:
template <typename T>
template <typename S>
auto Outer<T>::Inner<S>::func() -> Inner& {
...
}
通过使用上面示例中的尾随返回类型语法,您可以利用此时名称解析范围在Outer<T>::Inner<S>
范围内的事实,以便您可以使用Inner
的注入类名。
相关文章:
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- int(c) 和 c-'0' 之间的区别。C++
- 在cuda线程之间共享大量常量数据
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 嵌套类中 g++ 和 clang++ 之间的不同行为
- 模板转换运算符在 clang 6 和 clang 7 之间的区别
- 为什么 GCC 和 clang 之间编译的 c++17 lambda 存在差异?
- 在继承多个空类时,了解GCC/Clang vs MSVC2015之间的不同填充规则
- Objective-C源代码和clang -rewrite-objc C++代码之间有什么关系?
- GCC和Clang之间的C 不一致
- 为什么链接到librt会在g++和clang之间交换性能
- GCC和clang(SFINAE)之间的过载解决行为差异
- 编译一个相当简单的c++11程序时,gcc和clang之间的结果不同
- Clang - Windows 快照构建和版本 3.7.1 之间的区别
- MSVC和Clang之间的大括号不一致或初始化行为相等
- Clang和GCC中不明确基类转换之间的行为差异
- 重载解析在gcc和clang之间得到不同的结果
- struct和int之间clang中的重新定义不一致
- 编译器在g++4.7.2和英特尔13.0.1与clang++3.2和g++4.8之间的差异
- 对于未实例化的模板,在Clang和GCC之间获得类似的行为