[英]C++ store functions that forward universal references
Is it possible to store a function that has similar behaviour to the following function: 是否可以存储与以下功能具有相似行为的功能:
void target(int foo, size_t bar) {}
void target(std::string foo, int bar) {}
template<T...>
void forwarding_func(T&&... args)
{
target(std::forward<T>(args)...);
}
auto forwarding_callable = ?
How would one build the callable object for types T that has the same behaviour as the forwarding_func. 对于具有与forwarding_func相同行为的类型T,如何构建可调用对象。 I have to store it for later use, so I do need a std::function object?
我必须存储它以备后用,所以我确实需要一个std :: function对象吗? Is it possible to even store lambdas like these in function objects?
是否可以在函数对象中存储像这样的lambda?
auto f = [](auto&& x){
myfunction(std::forward<decltype(x)>(x));
}
You need a function object, that is, one with operator()
. 您需要一个函数对象,即一个带有
operator()
。 This operator should be a template and have the same (or similar) signature as forwarding_func
. 该运营商应该是一个模板,具有相同(或相似)的签名
forwarding_func
。 You can build one in a variety of ways. 您可以通过多种方式构建一个。
The most straightforward way is to use C++17 generic lambda. 最直接的方法是使用C ++ 17通用lambda。 If you can't use that, you can define your own:
如果您不能使用它,则可以定义自己的:
struct forwarder {
template <typename ... Args>
void operator()(Args&& ... args) { ... etc }
};
There is a completely different way to create such forwarders. 创建此类转发器的方式完全不同。 There is a proposal to add an
overload
function to the standard library. 建议将
overload
函数添加到标准库中。 You would use it like this: 您可以这样使用它:
auto callable = std::overload (
(void (*)(int, size_t))(target),
(void (*)(std::string, int))(target)
);
Compilers don't implement std::overload as it isn't a part of any standard yet, but you can easily implement it yourself or find an implementation on the net (see this question for example). 编译器尚未实现std :: overload,因为它尚未成为任何标准的一部分,但您可以自己轻松实现它,也可以在网上找到实现(例如,请参阅此问题 )。
Universal references and std::forward
only make sense in function templates, as in this case you don't know whether your argument is an lvalue-reference or not. 通用引用和
std::forward
仅在函数模板中有意义,因为在这种情况下,您不知道您的参数是否为左值引用。 If it is, you want to pass it on as is, if not, you want to move
it into the function you're forwarding to. 如果是,则希望按原样传递它;如果不是,则想
move
其移至要转发到的函数中。 That is exactly what std::foward
does. 这正是
std::foward
所做的。 Here 'sa very nice introduction to rvalue-references and perfect forwarding. 这里是有关右值引用和完美转发的很好的介绍。 As non-template functions specify whether they take their arguments by value or by (lvalue-)reference, you can just move or not move them accordingly and don't need
std::foward
. 由于非模板函数指定它们是通过值还是通过(lvalue-)引用接受参数,因此您可以相应地移动或不移动它们,而无需
std::foward
。
As function templates are not actually functions themselves, you cannot store them in a lambda. 由于功能模板本身并不是实际的功能,因此无法将其存储在lambda中。 You can however create a functor with a templated
operator()
: 但是,您可以使用模板化的
operator()
创建函子:
struct Forwarding_Functor
{
template<class... T>
void operator()(T&&... args)
{
target(std::forward<T>(args)...);
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.