本文介绍了将函数的参数-签名从使用`std :: function< T>`转换为模板参数类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my existing codebase, I have a non-template class and its constructor has the following declaration signature...

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;
}

上面的表示效果很好...

And the above representation works just fine...

我正在重构代码,我想对我的类进行模板化,我试图允许将类及其成员函数完全定义为constexpr ...

I'm in the process of refactoring my code and I want to template my class and I'm trying to allow the class and its member functions to be defined fully as constexpr...

我的班级的新签名应如下所示:

The new signature of my classes ought to look like this:

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}
    {}
};

我在这里遇到两个问题或困扰...

There are two issues or problems that I'm having here or struggling with...

ValueType 模板参数应该是 Func 模板参数的一部分...作为一个补充说明,所有函数指针,函子,lambda等.目前具有接受 T 类型的单个参数的形式,并且它们正在返回 T 类型的值.

The ValueType template argument should be a part of the Func template argument... And as a side note, all of the function pointers, functors, lambdas, etc. currently have the form of accepting a single parameter of type T and they are returning a value of type T.

另一个问题是更重要"的问题,当我尝试实例化一个对象时……

The other issue which is the "more important" issue involves when I try to instantiate an object...

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

对于函数指针的模板参数的语法,我感到困惑...以及能够将函数作为对象传递...

I'm getting confused about the syntax for the template arguments for the function pointers... along with being able to pass in a function as an object...

推荐答案

我建议不要为构造函数指定模板参数,而应提供类似的推导指南:

I would suggest not specifying the template parameters for the constructor, but instead provide a deduction guide like this:

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

然后您可以像这样调用构造函数:

and then you can call the constructor like this:

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

这是一个演示.

此外,没有理由将函数存储为指针,您可以将其存储为对象.正如评论中指出的那样,这样做的好处是您现在还可以存储有状态的lambda.

Additionally, there's no reason to store the function as a pointer, you could just store it as an object. As pointed out in the comments, this has the advantage that you can now store stateful lambdas as well.

这是演示.

这篇关于将函数的参数-签名从使用`std :: function&lt; T&gt;`转换为模板参数类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 07:37