jeudi 1 octobre 2015

Template argument deduction: which compiler is right here?

Consider the following code:

template<int N>
class Vector
{
};

#include <array>

template<int N>
void doWork(const Vector<N>&, const std::array<int,N>&)
{
}

int main()
{
    std::array<int,3> arr;
    Vector<3> vec;
    doWork(vec,arr);
}

Here Vector represents a class which is defined in a third-party library, and std::array is known to take its element count as std::size_t.

I've tried compiling this with clang-3.6 and g++-5.1. Clang worked without any complaint, while g++ gives the following error:

test.cpp: In function ‘int main()’:
test.cpp:17:19: error: no matching function for call to ‘doWork(Vector<3>&, std::array<int, 3ul>&)’
     doWork(vec,arr);
                   ^
test.cpp:9:6: note: candidate: template<int N> void doWork(const Vector<N>&, const std::array<int, N>&)
 void doWork(const Vector<N>&, const std::array<int,N>&)
      ^
test.cpp:9:6: note:   template argument deduction/substitution failed:
test.cpp:17:19: note:   mismatched types ‘int’ and ‘long unsigned int’
     doWork(vec,arr);
                   ^
test.cpp:17:19: note:   ‘std::array<int, 3ul>’ is not derived from ‘const std::array<int, N>’

I can work around this by doing a cast of N to std::size_t in second parameter of doWork() or calling doWork<3>(), but this wouldn't educate me.

So I rather ask first: which compiler is right here? Am I really doing something wrong in the code (so clang is too permissive), or is it indeed valid C++ (so that g++ has a bug)?

Aucun commentaire:

Enregistrer un commentaire