模板成员函数参数推导
Template member function argument deduction
我很好奇为什么以下模板推导不起作用(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; });
我想在这种情况下推导模板参数,这可能吗?
它不起作用,因为无法从 lambda 推导出 std::function
类型。编译器无法知道 F
可以从给定的 lambda 构造什么 std::function<F>
。第一个块中的最后两个示例仅起作用,因为正在使用 get(U u)
重载,而不是带有 std::function
参数的重载。
如果你希望能够接受 lambda,那么你需要有一个重载来接受通用的可调用类型而不是 std::function
。除非你解释你想做什么,否则很难给出更具体的方向。
我很好奇为什么以下模板推导不起作用(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; });
我想在这种情况下推导模板参数,这可能吗?
它不起作用,因为无法从 lambda 推导出 std::function
类型。编译器无法知道 F
可以从给定的 lambda 构造什么 std::function<F>
。第一个块中的最后两个示例仅起作用,因为正在使用 get(U u)
重载,而不是带有 std::function
参数的重载。
如果你希望能够接受 lambda,那么你需要有一个重载来接受通用的可调用类型而不是 std::function
。除非你解释你想做什么,否则很难给出更具体的方向。