C++ - 无法推断模板参数

C++ - Could not deduce template argument

我有一个使用模板编程的示例代码,运行在 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;
}

错误发生在A::run(a, b) => assign_array<0>::运行(improved_builtin &,const U [N]) ' : 无法从 'const int *'

中推断出 'const U [N]' 的模板参数

而且我注意到 improved_builtin 错误消息中有些奇怪的地方。在assign_arrayclass中,第一个参数的签名应该是improved_builtin。我不知道为什么美国出现在那里。有人知道这个错误吗?

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

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

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

当你将一个数组传递给一个函数时,它会衰减为一个指针,因此你将失去你试图从中推导出模板参数的大小。通过引用传递数组将保留类型并允许进行推导:

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

g++(和 clang)无论如何都能够编译您的示例的原因是它们使用您的 improved_builtin 参数来推断 U 的类型和 N 的值而不是数组类型。出于某种原因,VS2012 不执行此操作并尝试从数组中推断出无效,因为它已经衰减。如果您没有那个 improved_builtin 参数,您的示例根本无法编译。