模板成员函数参数推导

时间:2016-06-14 20:47:23

标签: c++ function templates std

我很好奇以下模板扣除为何不起作用(VS2015):

template<typename T>
class Foo
{
public:
  template<typename U>
  U get(U u) { return u; }

  // Default constructed U and T for example only.
  template<typename U>
  U get(std::function<U(U, T)> f) { return f(U(), T()); }

  template<typename U>
  U get(U u, std::function<U(U,T)> f) { return u; }

};

在上面的示例中,以下内容成功:

Foo<int> f;
auto f_asInt = f.get(5);      // f_asInt is of type int
auto f_asFloat = f.get(5.0f); // f_asFloat is of type float.

auto ff_asInt = f.get([](int, int) { return 5; });
auto ff_asFloat = f.get([](float, int) { return 5.0f; });

但是以下无法编译

Foo<int> f;
auto f_asInt = f.get(5, [](int, int) { return 5; });
auto f_asFloat = f.get(5.0f, [](float, int) { return 5.0f; });

我收到以下错误:

error C2784: 'U Foo<int>::get(U,std::function<U(U,T)>)': could not deduce template argument for 'std::function<U(U,T)>' from 'main::<lambda_c4fa8cb1e6fa86997f25b7dabd5d415f>'

如果我拼出整个模板,它会按预期工作。

Foo<int> f;
auto f_asInt = f.get<int>(5, [](int, int) { return 5; });
auto f_asFloat = f.get<float>(5.0f, [](float, int) { return 5.0f; });

我想在这种情况下推导出模板参数,甚至可能吗?

1 个答案:

答案 0 :(得分:4)

它不起作用,因为std::function类型无法从lambda中推断出来。编译器无法知道可以从给定的lambda构造F std::function<F>。第一个块中的最后两个示例仅起作用,因为正在使用get(U u)重载,而不是具有std::function参数的重载。

如果您希望能够接受lambdas,那么您需要具有接受通用可调用类型而不是std::function的重载。除非你解释你正在尝试做什么,否则很难给出更具体的指导。