使用模板函数进行clang编译错误

时间:2015-01-01 20:12:18

标签: c++ c++11 clang

我正在编译一些代码(我用微软编写并编译好了 工具链与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'。 这个错误的根源是什么?

2 个答案:

答案 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;
}