SSCCE:
#include <functional>
using std::function;
using std::forward;
template<typename ToType, typename... FromTypes>
ToType construct(FromTypes&&... fromTypes) {
return ToType(forward<FromTypes>(fromTypes)...);
}
class Maybe {
public:
Maybe() : m_value(42.0f) {}
template<typename Function>
auto apply(Function function) const -> decltype(function(std::declval<float>())) {
return function(value());
}
private:
float const& value() const {
return m_value;
}
float m_value;
};
int main() {
Maybe a;
a.apply(construct<int, float>);
return 0;
}
给出错误:
test.cpp: In instantiation of ‘decltype (function(declval<float>())) Maybe::apply(Function) const [with Function = int (*)(float&&); decltype (function(declval<float>())) = int]’:
test.cpp:31:32: required from here
test.cpp:17:28: error: invalid initialization of reference of type ‘float&&’ from expression of type ‘const float’
return function(value());
^
value()
从错误消息来看,返回 a显然是一个问题const&
。
这里的关键点是,类型不是在第 17 行推导出来的,值被传递给它。construct
当函数被传递到apply
第 31 行时,类型被分配。
我为模板指定了错误的类型construct
。 construct<int, float>
. 如果我使用construct<int, float const&>
它的功能就好了。
但是,这很麻烦,并且需要了解apply
. 而且它也永远不会绑定左值,因为T
和T&&
是不同的类型。(因为缺少类型推导。)
有没有办法让我可以将一个函数传递给另一个函数并在调用它的站点上进行类型推导,这样我就可以或多或少地对调用者透明地进行完美转发?或者是否有另一种方法可以实现这一目标,不会将复杂性泄露给调用者?