【发布时间】:2021-05-01 21:12:18
【问题描述】:
我似乎无法弄清楚为什么以下代码不起作用:
#include <array>
template <long unsigned int s> void a() {}
template <long unsigned int s> void b(const std::array<int, s>& arr) {
a<arr.size()>(); // error: no matching function for call to 'a'
}
int main() {
const std::array<int, 2> arr {{0, 0}};
a<arr.size()>(); // Works
b<arr.size()>(arr);
return 0;
}
GCC 失败并显示以下内容:
test.cpp: In instantiation of ‘void b(const std::array<int, s>&) [with long unsigned int s = 2]’:
test.cpp:13:22: required from here
test.cpp:6:18: error: no matching function for call to ‘a<(& arr)->std::array<int, 2>::size()>()’
6 | a<arr.size()>(); // Doesn't
| ~~~~~~~~~~~~~^~
test.cpp:3:37: note: candidate: ‘template<long unsigned int s> void a()’
3 | template <long unsigned int s> void a() {}
| ^
test.cpp:3:37: note: template argument deduction/substitution failed:
test.cpp:6:18: error: ‘arr’ is not a constant expression
6 | a<arr.size()>(); // Doesn't
| ~~~~~~~~~~~~~^~
test.cpp:6:15: note: in template argument for type ‘long unsigned int’
6 | a<arr.size()>(); // Doesn't
| ~~~~~~~~^~
我认为‘arr’ is not a constant expression 部分是最相关的,但我不明白为什么同一行在main() 中有效(那里是一个常量表达式吗?),以及为什么将arr 作为const 传递副本(而不是参考)也可以解决问题。
PS:我知道我可以使用a<s>();,但我只是想弄清楚这个错误的含义。
【问题讨论】:
-
函数参数不能用作常量表达式。
-
@cigien 如果我将 b 的签名更改为
void b(const std::array<int, s> arr)(通过副本),则没有错误。那不是使用函数参数作为常量表达式吗? -
嗯,那不应该编译。某处可能有一个正确的欺骗,但我使用的那个不是,所以我重新打开了。
-
这是一个合理的target。看来
std::array通过 value 传递给函数可以用作常量表达式,但如果它是通过 reference 传递的,则不能。
标签: c++ templates const-reference