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

时间:2015-05-12 08:29:50

标签: c++ templates visual-studio-2012

我有一个使用模板编程的示例代码,它在linux上运行良好。但是当我尝试将它带到visual studio 12的窗口时,我得到了关于模板参数推导的编译错误。以下是导致错误的代码部分:

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)=&gt; assign_array&lt; 0&gt; :: run(improved_builtin&amp;,const U [N])&#39; :无法推断出&#39; const U [N]&#39;的模板参数。来自&#39; const int *&#39;

我注意到错误消息中有一些奇怪的东西,就是Improved_builtin。在assign_array类中,第一个参数的签名应为improved_builtin。我不知道为什么美国出现在那里。有人对这个错误有任何想法吗?

2 个答案:

答案 0 :(得分:3)

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

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参数,你的例子根本就不会编译。

答案 1 :(得分:1)

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

“更改Improved_builtin并运行以通过引用获取数组可能会起作用:const T(&amp; v)[N]和const U(&amp; b)[N]”

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