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

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

问题描述:

给定以下代码

#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);
}

实例

为什么我会收到错误

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);
                                         ^

编译器难道不能从v的类型推导出模板参数Base吗?

Shouldn't the compiler be able to deduce the the template parameter Base from the type of v?

我可以通过将第 27 行更改为

I can rectify this by changing line 27 to

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

但这感觉没有必要.

编译器难道不能从v的类型推导出模板参数Base吗?

Shouldn't the compiler be able to deduce the the template parameter Base from the type of v ?

调用makeBaseVec时,模板类型推导机制不考虑v的类型.如果您要调用该函数并丢弃返回值怎么办?

The type of v is not considered by the template type deduction mechanism when you call makeBaseVec. What if you were to call the function and discard the return value?

返回类型不参与类型推导或重载解析.

Return types do not participate in type deduction or overload resolution.

如果你不想重复,你可以在 v 上使用类型推导:

If you don't want to repeat yourself, you can use type deduction on v instead:

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

事实上,对于变量来说,auto 几乎总是一个很好的策略.

In fact, almost always auto is a good policy for variables.