我正在编译一些代码(我用微软编写并编译好了 工具链与clang。以下是一些我不理解错误的代码:
#include <iostream>
#include <bitset>
template <int N>
auto foo(int index, std::bitset<N> & already_given)->int
{
return 0;
}
auto bar()->void
{
auto const n = 10;
auto baz = std::bitset<n>{};
for (auto i = 0; i < n; i++) {
std::cout << foo(i, baz)
<< std::endl;
}
}
给我错误no matching function to call to 'foo'
。
这个错误的根源是什么?
答案 0 :(得分:6)
std::bitset
是一个类模板,其参数为std::size_t
:
template< std::size_t N >
class bitset;
执行auto baz = std::bitset<n>{};
时,n
可以隐式转换为std::size_t
,但在模板参数推断期间,类型必须完全匹配[temp.deduct.type] / p17:
如果在具有非类型模板参数的函数模板的声明中,在函数的表达式中使用非类型模板参数参数列表,如果推导出相应的 template-argument , template-argument 类型应与 template-parameter 的类型完全匹配,除了从数组绑定推导出的 template-argument 可能是任何整数类型。
非类型模板参数int N
从整数中推导出参数,该整数与bitset的类型不匹配,因此您有一个演绎失败。
要解决此问题,您需要更改参数以匹配类型:
template <std::size_t N>
auto foo(int index, std::bitset<N>& already_given) -> int;
答案 1 :(得分:1)
bitset<N>
是一个声明如下的类模板[template.bitset]:
namespace std {
template <size_t N> class bitset;
}
其非类型模板参数的类型为size_t
,而非int
,[support.types] / p6:
类型
size_t
是一个实现定义的无符号整数类型,其大小足以包含任何对象的字节大小。
因此,您应该按如下方式重写您的功能模板:
#include <cstddef> // size_t
template <std::size_t N>
// ~~~~~~~~~~^
auto foo(int index, std::bitset<N> & already_given)->int
{
return 0;
}