【问题标题】:Function-style template syntax函数式模板语法
【发布时间】:2018-09-08 02:02:47
【问题描述】:

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

目前,这是我的代码:

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 传递给doubleArgs 传递给double,它将double(double) 传递给R 而没有传递给Args .

According to cppreferencestd::function 的模板参数是template&lt; class R, class... Args &gt;。因此,如果我给它A(B,C),它将传递A 用于参数RB,C 用于可变参数Args。但是,当我将它传递给我的班级时,它会将A(B,C) 传递给R,而没有传递任何可变参数Args

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

【问题讨论】:

  • 因为它们的写法不同。对函数类型使用偏特化
  • auto delayed = std::bind(doubleMe, 2.); 后跟 delayed() ?
  • @Jarod42 我考虑过这一点,虽然它会起作用,但拥有一个类似的类对我来说更方便。

标签: c++ templates c++14 variadic


【解决方案1】:

因此,如果我给它A(B,C),它将通过A 为参数RB,C 为可变参数Args

是的,但不是出于您认为的原因。如果仔细观察,您会发现 std::function 部分专门用于任何函数类型:

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

你可以把它想象成非常原始的模式匹配。如果你用int(int, double) 实例化function,那么RintArgsint, double 是有意义的。如果(部分)特化比包罗万象的通用主模板更匹配,则选择它,这就是这里发生的情况。

记住: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;
};

希望它能消除混乱。

【讨论】:

  • 这是有道理的。感谢您的回答!
猜你喜欢
  • 2011-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多