还有一个decltype(auto)模板-参数问题。这一次,我能够创建用于再现错误的最小代码如下所示:
template <template <decltype(auto)> class TT, decltype(auto) V>
void foo(TT<V>) {
};
template <decltype(auto)>
struct Bar{};
int x;
int main() {
foo(Bar<(x)>{});
}在[嘎吱声]中这样做的结果是:
prog.cc:11:5: error: no matching function for call to 'foo'
foo(Bar<(x)>{});
^~~
prog.cc:2:6: note: candidate template ignored: substitution failure [with TT = Bar]: non-type template argument is not a constant expression
void foo(TT<V>) {
^
1 error generated.[gcc]接受代码。
据我所知,代码是格式良好的,clang在其解释中是错误的,但是在向lvvm提交bug之前需要确认。我说的对吗?
发布于 2017-09-21 13:18:12
根据错误,clang在推导模板参数时没有问题,模板参数也是标准兼容的- [temp.arg.template]/3 (移除地雷):
模板-参数匹配模板参数P,当P至少和模板参数A一样专门化时。如果P包含参数包,则如果A的每个模板参数与P的模板参数列表中的相应模板参数匹配,则A也匹配P。两个模板参数匹配,如果它们是相同类型的(类型、非类型、模板),对于非类型模板参数,它们的类型是等效的(temp.over.link),对于模板模板-参数,它们各自对应的模板参数都递归匹配。当P的模板参数列表包含模板参数包时,模板参数包将匹配与P中的模板参数包具有相同类型和形式的模板参数列表中的零或多个模板参数或模板参数包(忽略这些模板参数包是否是模板参数包)。
现在让我们确定Bar<(x)>{}应该作为参考。这是由[dcl.type.auto.deduct]/5和[dcl.type.simple]/4覆盖的。
最后,让我们检查一下,我们是否真的可以使用以链接作为模板参数[temp.arg.nontype]/2的对变量的引用。
非类型模板参数的模板参数应该是模板参数类型的转换常量表达式。对于引用或指针类型的非类型模板参数,常量表达式的值不应引用(或对指针类型而言,不应是的地址):
[over.over注释:如果模板参数表示一组重载函数(或指向此类函数的指针或成员指针),则从集合( )中选择匹配函数。- end注意事项 ]
推导出的论点符合要求。这使得代码格式良好,并暗示了clang的错误。
https://stackoverflow.com/questions/46328005
复制相似问题