为什么编译器不能从返回类型中推导出模板参数?

时间:2017-07-13 08:47:36

标签: c++ templates

给出以下代码

#include <vector>
#include <memory>

using namespace std;

class MyBase
{};

class MyDerived : public MyBase
{};

template<class Base, class Derived>
vector<Base> makeBaseVec(const Derived& obj, const typename vector<Base>::size_type size)
{
    vector<Base> out;
    for (typename vector<Base>::size_type i = 0; i < size; i++)
    {
        out.push_back(Base(obj) /* copy constructor */);
    }

    return out;
}

int main()
{
    MyDerived a;
    vector<MyBase> v = makeBaseVec<MyBase>(a, 10);
}

Live example

为什么我会收到错误

main.cpp:13:14: note:   template argument deduction/substitution failed:
main.cpp:29:41: note:   couldn't deduce template parameter 'Base'
     vector<MyBase> v = makeBaseVec(a, 10);
                                         ^

编译器是否应该能够从Base的类型中推导出模板参数v

我可以通过将第27行改为

来纠正这个问题
vector<MyBase> v = makeBaseVec<MyBase>(a, 10);

但这感觉不必要。

1 个答案:

答案 0 :(得分:7)

  

编译器是否应该能够从v的类型中推断出模板参数Base?

当您致电v时,模板类型扣减机制不会考虑makeBaseVec的类型。如果您要调用该函数并丢弃返回值该怎么办?

返回类型不参与类型扣除或重载解析。

如果您不想重复自己,可以在v上使用类型扣除:

auto v = makeBaseVec<MyBase>(a, 10);

事实上,几乎总是auto是一个很好的变量政策。