c++,不能推断出模板参数

时间:2021-07-21 07:19:00

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:

我有一个使用模板编程的示例代码,它在linux上运行良好。但是当我尝试将它带进visual studio 12的windows时,我得到了关于模板参数演绎的编译错误。下面是导致错误的代码片段:

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 *'

错误发生在A:::run(A, b) => assign_array<0>::run(ved_builtin &,const U [N])':无法从“const int *”中推导出“const U [N]”的模板参数

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?

我注意到在错误信息中有一些奇怪的地方,那就是改进。在assign_array类中,第一个参数的签名应该是improved_builtin。我不知道我们为什么会出现在那里。有人知道这个错误吗?

2 个解决方案

#1


3  

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.

g++(和clang)能够编译示例的原因是,它们使用您的改进d_builtin参数来推断U的类型和N的值,而不是数组类型。出于某种原因,VS2012没有这么做,而是试图从数组中推断,这是无效的,因为它已经衰减了。如果您没有那个improved_builtin参数,那么您的示例就不会编译。

#2


1  

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

解决方案正如TartanLlama和Johny在评论中提到的。但选择了塔塔塔姆的兵法,因为它更容易修改:

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

“改变改进的结构和运行以引用数组的方式可能会起作用:const T (&v)[N]和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++.

这是因为通过引用传递可以帮助我们保留数组的大小。但是我仍然不知道为什么它可以使用g++编译和运行。

#1


3  

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.

g++(和clang)能够编译示例的原因是,它们使用您的改进d_builtin参数来推断U的类型和N的值,而不是数组类型。出于某种原因,VS2012没有这么做,而是试图从数组中推断,这是无效的,因为它已经衰减了。如果您没有那个improved_builtin参数,那么您的示例就不会编译。

#2


1  

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

解决方案正如TartanLlama和Johny在评论中提到的。但选择了塔塔塔姆的兵法,因为它更容易修改:

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

“改变改进的结构和运行以引用数组的方式可能会起作用:const T (&v)[N]和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++.

这是因为通过引用传递可以帮助我们保留数组的大小。但是我仍然不知道为什么它可以使用g++编译和运行。