无法推断出模板类型

Q-b*_*uit 9 c++ templates template-argument-deduction

我正在尝试将迭代器作为模板参数传递给模板方法,但编译器抱怨:

error C2783: 'void Test::Assert(std::vector<T>::const_iterator)':
could not deduce template argument for 'T'
Run Code Online (Sandbox Code Playgroud)

产生错误的代码是:

#include "stdafx.h"
#include <iostream>
#include <vector>

class Test
{
    public:
        template <typename T>
        void Assert(typename std::vector<T>::const_iterator it)
        {
            std::cout << *it << std::endl;
        }
};

int _tmain(int argc, _TCHAR* argv[])
{
    Test test;

    std::vector<double> myVec;

    test.Assert(myVec.cbegin());

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我猜有一种简单的方法可以使这项工作,因为大多数std算法可以从迭代器中推断出类型.

Bar*_*rry 14

其原因是,你有表格T中是一个非上下文推断:

template <typename T>
void Assert(typename std::vector<T>::const_iterator it)
Run Code Online (Sandbox Code Playgroud)

考虑一个更简单的案例来理解为什么:

struct A { using type = int; };
struct B { using type = int; };
struct C { using type = int; };

template <typename T>
void Assert(typename T::type it) { ... }

Assert(5);
Run Code Online (Sandbox Code Playgroud)

应该T推断出什么?这是不可能确定的.你必须明确提供类型......就像Assert<A>(5).

另请参见什么是非弱化上下文?

因为大多数std算法都可以从迭代器推导出类型.

那是因为标准算法只推导出迭代器类型,而不是容器类型.例如std::find,只是:

template <class InputIt, class T>
InputIt find( InputIt first, InputIt last, const T& value );
Run Code Online (Sandbox Code Playgroud)

这里根本没有"容器"的概念 - 它只是需要推导出的迭代器类型.这是算法库之美的一部分.

因此,如果你想要做的只是输出迭代器的内容,那么正确的函数就是:

template <typename Iterator>
void Assert(Iterator it)
{
    std::cout << *it << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

当你打电话时Assert(myVec.cbegin()),Iterator会被推断为std::vector<double>::const_iterator,这正是你想要的.


归档时间:

查看次数:

1067 次

最近记录:

11 年,6 月 前