简体   繁体   中英

C++ - Could not deduce template argument

I have a sample code which makes use of template programming, it runs fine on linux. But when I try to bring it to windows with visual studio 12, I got compile error about template argument deduction. Here is the fraction of code that cause the error:

template <int I>
class assign_array
{
public:
    template <typename U, unsigned N>
    static inline void run(improved_builtin<U, N>& a, const U b[N])
    {
        // do sth
    }
};

template <template <int> class A, int I, int E>
struct loop_iter
{
    template <typename U, typename V>
    static inline void iter(U& a, V& b)
    {
       A<I>::run(a, b); // get error here
    }
};

template <typename T, unsigned N>
improved_builtin<T, N>::improved_builtin(const T v[N])
{
    loop_iter<assign_array, 0, N - 1>::iter(*this, v);
    return;
}

The error occurs at A::run(a, b) => assign_array<0>::run(improved_builtin &,const U [N])' : could not deduce template argument for 'const U [N]' from 'const int *'

And I have noticed something strange in the error message which is improved_builtin. In the assign_array class, the signature of the first argument should be improved_builtin. I have no idea why US appears there. Anyone has any idea about this error?

When you pass an array in to a function it will decay to a pointer, so you will lose the size that you are trying to deduce a template argument from. Passing the array by reference will preserve the type and allow the deduction to take place:

static inline void run(improved_builtin<U, N>& a, const U (&b)[N])
//                                       take by reference ^

The reason that g++ (and clang) are able to compile your example anyway is that they use your improved_builtin argument to deduce the type of U and the value of N instead of the array type. For some reason VS2012 doesn't do this and tries to deduce from the array, which isn't valid because it has decayed. If you didn't have that improved_builtin argument, your example wouldn't compile at all.

The solution is as mentioned by TartanLlama and Johny in the comments. But chose TartanLlama's soltution cause it's easier to modify:

"Changing improved_builtin and run to take the array by reference instead might work: const T (&v)[N] and const U (&b)[N]"

This is because passing by reference help us to preserve the array size. But I still haven't known why it can compile and run using g++.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM