将函数的参数-签名从使用`std::function<T>`转换为模板参数类型。

问题描述 投票:0回答:1

在我现有的代码库中,我有一个非模板类,它的构造函数有如下声明签名......。

struct SomeStruct {
    double a_;
    double b_;
    SomeStruct(double a, double b) : a_{a}, b_{b} {}
}

class SomeClass {
private:
    SomeStruct fields_;
    size_t n_;
    std::function<double(double)> func_;
public:
    SomeClass(SomeStruct fields, size_t n, std::function<double(double)> func) :
      fields_{fields}, n_{n}, func_{func}
    {}
};

我是这样使用的。

constexpr double funcA(double x) {
    return x;
}

constexpr double funcB(double x) {
    return x*x;
}

int main() {
    SomeClass a(SomeStruct{1.0, 5.0}, 1000, &funcA);
    SomeClass b(SomeStruct{3.5, 7.7}, 2000, &funcB);

    return 0;
}

上面的表达方式也很好... ...


我正在重构我的代码,我想把我的类做成模板,我想让类和它的成员函数完全定义为constexpr...

我的类的新签名应该是这样的。

template<typename Field>
struct SomeStruct {
    Field a_;
    Field b_;
    constexpr SomeStruct(Field a, Field b) : a_{a}, b_{b} {}
};

template<typename FieldType, typename ValueType, typename Func>
class SomeClass {
    SomeStruct<FieldType> fields_;
    size_t n_;
    // std::function<double(double)> func_; // No longer using `std::function` since I want this to be constexpr
    Func* func_; // would like to save a pointer to a function, functor, function object, or lambda instead...
   public:
    SomeClass(SomeStruct<FieldType> fields, size_t n, Func* func) :
      fields_{fields}, n_{n}, func_{func}
    {}
};

有两个问题,或者说是我正在努力解决的问题...

我在这里遇到了两个问题,或者说是在努力解决 ValueType 模板参数应该是 Func 模板参数... 还有一点,目前所有的函数指针、漏斗、lambdas等的形式都是接受一个类型为 T 并且它们返回一个类型为 T.

另一个 "更重要 "的问题是,当我试图实例化一个对象时......我对函数指针的模板参数的语法感到困惑......以及能否将函数作为对象传入......。

SomeClass<double, double, ?> a{ SomeStruct{ 3.0, 5.0 }, 1000, &funcA }; 

我对函数指针的模板参数的语法感到困惑......以及能否将函数作为一个对象传入......。

c++ templates parameters c++17 constexpr
1个回答
4
投票

我建议不要为构造函数指定模板参数,而是提供一个类似这样的推导。

template<typename FieldType, typename ValueType, typename Func>
SomeClass(SomeStruct<FieldType>, ValueType, Func*)
 -> SomeClass<FieldType, ValueType, Func>;

然后你可以像这样调用构造函数。

SomeClass a{ SomeStruct{ 3.0, 5.0 }, 1000, &funcA }; 

这里有一个 演示.

此外,没有理由将函数存储为指针,你可以直接将其存储为一个对象。正如评论中指出的那样,这样做的好处是现在你也可以存储有状态的lambdas。

下面是一个 演示 的。

© www.soinside.com 2019 - 2024. All rights reserved.