我偶然发现了typedef和各种模板参数之间的奇怪交互,我想了解这些参数。下面的代码使用clang编译,但是使用GCC时出现了一个错误:
template<typename T> // no error if this is not a template
struct Traits;
#pragma GCC diagnostic ignored "-Wunused-parameter"
template<typename ...args>
void function(args... e) {}
template<typename T>
struct Caller {
typedef typename Traits<T>::types traits_types; // no error if this is changed to a 'using' directive
template<typename ...types> // no error if the pack is converted to a single parameter
static void method(types... e) {
function<traits_types>(e...);
}
};GCC行为
当我与GCC一起编译(而不是链接)时,我在第14行中得到了一个错误:
$ g++-9.2.0 -Wall -Wpedantic -Wextra -std=c++11 -c test.cpp
test.cpp: In static member function ‘static void Caller<T>::method(types ...)’:
test.cpp:14:31: error: parameter packs not expanded with ‘...’:
14 | function<traits_types>(e...);
| ~~~~~~~~~~~~~~~~~~~~~~^~~~~~
test.cpp:14:31: note: ‘types’
$它的作用就好像GCC在traits_types的定义中第一个替代了,这将产生
template<typename ...types>
static void method(types... e) {
function<typename Traits<T>::types>(e...);
}然后计算模板参数替换,此时它将令牌types的最后一次出现视为未展开的参数包,并相应地生成一个错误。
我在GCC 6.4.0、7.3.0、8.2.0、8.3.0、9.1.0和9.2.0以及几个较早的版本中测试了这一点,它们的行为都是一致的。
clang行为
但是,当我用clang编译它时,它工作得很好。
$ clang++-8 -Wall -Wpedantic -Wextra -std=c++11 -c test.cpp
$这似乎是它首先替代了参数pack types,然后处理名称traits_types。
在clang 6.0.0、7.0.1和8.0.1以及几个较早的版本中,我看到了这种行为。
问题
在标准C++11中,GCC给出的错误是正确的,还是代码有效?或者是未定义/实现-定义/其他未指定?
我查看了CpPreence.com关于模板和类型防御的内容的大部分内容,但没有找到任何明确解决这个问题的方法。我还检查了其他几个问题(1、2、3.、4.、5等),据我所知,所有这些问题似乎都类似,但并不完全适用于这种情况。
如果这实际上是一个编译器错误,链接到bug跟踪器中的相关问题,确认GCC (或clang,如果适用)没有正确处理这一问题将很好地解决这个问题。
发布于 2019-11-16 14:17:19
是的是虫子。你所观察到的“它的作用就像GCC在traits_types定义中第一次替代”,然后是GCC虫90189的一种表现形式。
来源: 结构A{使用CommonName = char;};模板结构B{使用V= typename T::CommonName;};模板结构B;输出:7:37: error:参数包没有用‘.’展开的参数包,使用V= typename T::CommonName;\x^ :7:37:注意:'CommonName‘编译器返回:1 被GCC所有版本所拒绝。由clang,msvc接受。
GCC的行为就像您直接编写了typename Traits<T>::types,然后它被依赖的名称types与模板参数包的名称相同而混淆了。您可以通过给包指定不同的名称来绕过它,但是在标准的C++中,依赖的名称可以与包的名称相同。因为其中一个必须是合格的,而另一个是不合格的,所以不应该有含糊之处。
https://stackoverflow.com/questions/58891286
复制相似问题