代码之家  ›  专栏  ›  技术社区  ›  Andreas Loanjoe

C++存储转发通用引用的函数

  •  1
  • Andreas Loanjoe  · 技术社区  · 7 年前

    是否可以存储与以下函数具有类似行为的函数:

    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 = ?
    

    如何为与forwarding\u func具有相同行为的类型T构建可调用对象。我必须存储它以备将来使用,所以我确实需要一个std::function对象?甚至可以在函数对象中存储这样的lambda吗?

    auto f = [](auto&& x){
          myfunction(std::forward<decltype(x)>(x));
    } 
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   n. m. could be an AI    7 年前

    你需要一个函数对象,也就是一个 operator() . 该运算符应为模板,并具有与相同(或类似)的签名 forwarding_func . 您可以通过多种方式构建一个。

    struct forwarder {
        template <typename ... Args>
           void operator()(Args&& ... args) { ... etc }
    };
    

    有一种完全不同的方式来创建这样的转发器。有人提议添加一个 overload

    auto callable = std::overload (
       (void (*)(int, size_t))(target),
       (void (*)(std::string, int))(target)
    );
    

    编译器不实现std::重载,因为它还不是任何标准的一部分,但您可以轻松地自己实现它或在网上找到一个实现(请参阅) this question 例如)。

        2
  •  0
  •   Knoep    7 年前

    通用参考和 std::forward 只有在函数模板中才有意义,因为在这种情况下,您不知道您的参数是否是左值引用。如果是,你想按原样传递,如果不是,你想 move 将其输入到您要转发的函数中。这就是为什么 std::foward Here 这是对右值引用和完美转发的一个很好的介绍。 由于非模板函数指定它们是按值还是按(左值-)引用获取参数,因此您可以相应地移动或不移动它们,而不需要 标准::福沃德

    由于函数模板本身实际上不是函数,因此不能将其存储在lambda中。但是,您可以使用模板创建函子 operator() :

    struct Forwarding_Functor
    {
        template<class... T>
        void operator()(T&&... args)
        {
            target(std::forward<T>(args)...);
        }
    };