【问题标题】:Why can't the compiler deduce template parameter from return type?为什么编译器不能从返回类型中推断出模板参数?
【发布时间】:2017-07-13 08:47:35
【问题描述】:

给定以下代码

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

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

我可以通过将第 27 行更改为来纠正此问题

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

但这感觉没有必要。

【问题讨论】:

  • 模板参数推导不适用于返回值。

标签: c++ templates


【解决方案1】:

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

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

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

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

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

事实上,几乎总是auto 是变量的好策略。

【讨论】:

  • 哦,那是我出错的地方。我在想编译器会考虑v 的类型,如果可能的话,我只需要在不可能的情况下声明类型。谢谢!
  • 不清楚最后一个使用“auto”的建议与 OP 的问题有何关系。
  • @nbubis - 你不确定哪一部分?您不明白为什么 OP 对他们最初修复错误的方式不满意?为什么我猜这是困扰他们的重复?还是别的什么?
猜你喜欢
  • 2012-03-26
  • 2020-09-24
  • 1970-01-01
  • 1970-01-01
  • 2015-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多