mookid
mookid

Reputation: 1172

clang compilation error with template function

I'm compiling some code (which I wrote and compiled fine with the microsoft toolchain) with clang. Here is some piece of code for which I do not understand the error:

#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;
        }
}

gives me the error no matching function to call to 'foo'. What is the source of this error?

Upvotes: 1

Views: 295

Answers (2)

David G
David G

Reputation: 96790

std::bitset is a class template that takes its argument as a std::size_t:

template< std::size_t N >
class bitset;

When doing auto baz = std::bitset<n>{};, n is implicitly-convertible to std::size_t, but during template argument deduction the types must match exactly [temp.deduct.type]/p17:

If, in the declaration of a function template with a non-type template-parameter, the non-type template-parameter is used in an expression in the function parameter-list and, if the corresponding template-argument is deduced, the template-argument type shall match the type of the template-parameter exactly, except that a template-argument deduced from an array bound may be of any integral type.

The non-type template parameter int N deduces the argument from an integer, which doesn't match the type of the bitset, so you have a deduction failure.

To fix this, you need to change your parameter to match the type:

template <std::size_t N>
auto foo(int index, std::bitset<N>& already_given) -> int;

Upvotes: 6

Piotr Skotnicki
Piotr Skotnicki

Reputation: 48447

bitset<N> is a class template declared as follows [template.bitset]:

namespace std {
  template <size_t N> class bitset;
}

Its non-type template parameter is of the type size_t, not int, [support.types]/p6:

The type size_t is an implementation-defined unsigned integer type that is large enough to contain the size in bytes of any object.

Therefore, you should rewrite your function template as follows:

#include <cstddef> // size_t

template <std::size_t N>
//        ~~~~~~~~~~^
auto foo(int index, std::bitset<N> & already_given)->int
{
        return 0;
}

Upvotes: 1

Related Questions