代码之家  ›  专栏  ›  技术社区  ›  User9123

函数样式模板语法

  •  2
  • User9123  · 技术社区  · 7 年前

    我正在尝试编写一个相当简单的类,它接受一个函数和一些参数,并且可以在以后使用这些参数执行函数。

    目前,这是我的代码:

    template<typename R, typename... Args>
    class Delayed
    {
    public:
        using FunctionT = std::function<R(Args...)>;
    
        Delayed(FunctionT func, Args... args) : func(func), args(std::forward<Args>(args)...)
        {
    
        }
    
    private:
        FunctionT func;
        std::tuple<Args...> args;
    };
    
    int main()
    {
        std::function<double(double)> doubleMe = [](double x) { return x * 2.0; };
    
        //Works
        Delayed<double, double> delayed1(doubleMe, 2.0);
    
        //Doesn't work
        Delayed<double(double)> delayed2(doubleMe, 2.0);
    }
    

    问题是当我通过的时候 double(double) 作为论点,而不是 R 存在 double Args 存在 双重的 ,它通过了 双人(双人) R 也没什么 参数

    According to cppreference ,的模板参数 std::function template< class R, class... Args > 。所以如果我给它 A(B,C) ,它将通过 A 对于参数 R B,C 对于可变参数 参数 。但当我把它传给我的班级时,它就通过了 A(B,C) 对于 R 对变量参数不传递任何内容 参数

    这个函数语法应该如何使用,为什么它适用于 std::函数 但不是我的班级?

    1 回复  |  直到 7 年前
        1
  •  3
  •   Rakete1111    7 年前

    所以如果我给它 A(B,C) ,它将通过 A 对于参数 R B,C 对于可变参数 Args

    是的,但不是因为你想的原因。如果你仔细看,你会看到的 std::function 部分专用于任何函数类型:

    template<typename R, typename... Args>
    class function<R(Args...)>;
    //            ^^^^^^^^^^^^
    

    您可以将其想象为非常原始的模式匹配。如果您实例化 function 具有 int(int, double) ,那么有意义的是 R int 参数 int, double 。如果(部分)专门化比catch-all泛型主模板更好匹配,那么就会选择它,这就是这里发生的情况。

    请记住: double(double) 是一种类型,是一种函数。没有任何特殊规则涉及它。因此,在您的情况下,您可以这样做:

    template<typename R, typename... Args>
    class Delayed<R(Args...)> : public Delayed<R, Args...> {
      //         ^^^^^^^^^^^^
      //       partially specialize to decompose function types
    
      // We need to inherit constructors (only).
      using Delayed<R, Args...>::Delayed;
    };
    

    希望它能消除困惑。