gpt4 book ai didi

c++ - 可以接受未知签名的可变函数引用的类

转载 作者:行者123 更新时间:2023-11-30 03:35:55 26 4
gpt4 key购买 nike

我想创建一个类,而不是在实例化时接受数量可变的函数引用,这些函数引用事先没有已知的签名。这是一个几乎可以满足我要求的示例:

// To show the function refs being used 
void p(int arg) { cout << "int " << arg << endl; }
void p(string arg) { cout << "string " << arg << endl; }
void p(int arg1, int arg2) { cout<<"int/int "<<arg1<<arg2<<endl; }
void p(int arg1, string arg2) { cout<<"int/string "<<arg1<<arg2<<endl; }

class foo {
public:
// CTOR takes variadic function refs
template <typename... Args>
foo(Args... args) { p(args()...); }
// "args()..." requires supplied functions to take no parameters
// but makes no requirement on their return values.
};

// Using lambdas, but free functions, std::bind(), etc. work too
foo i([]{return 1;}); // prints "int 1"
foo s([]{return string("one");}); // prints "string one"
foo b([]{return 2;},
[]{return string("two");}); // prints "int/string 2two"

我看不出如何解决这个问题,这样作为参数提供的函数就不会在构造函数中求值。我希望稍后通过 foo 中的另一种方法调用 p(args()...)。这就是为什么 foo 不能像 foo i(1) 那样简单地创建的原因:参数函数需要稍后调用,并且需要多次调用,而不仅仅是在创建对象时调用一次(而且它们会比仅仅返回一个常量更复杂)。

问题似乎归结为保存对稍后调用的构造函数参数的引用,当类不知道这些参数有多少或有什么签名时。参数需要以某种方式成为类模板的一部分,而不仅仅是构造函数模板,但是如何呢?

如果传递的函数都具有相同的签名,那么可以使用带有非类型参数的类模板并将函数作为模板参数提供:

template <int (&...Arg)()>
class bar {
public:
bar() { p(Arg()...); }
other() { p(Arg()...); } // Use in any method
};

int one() { return 1; }
int two() { return 2; }
bar<one> bi; // Prints "int 1"
bar<one, two> bii; // Prints "int/int 12"

但这要求所有参数都是返回 int 的函数,并且也不适用于 lambda,因为它们不能是模板参数。

最佳答案

您可以使用 lambda 和 std::function 来做到这一点。
请注意,lambda 可以捕获参数包并(让我说)稍后解包。
它遵循一个最小的工作示例:

#include<iostream>
#include<functional>

void p(int arg) { std::cout << "int " << arg << std::endl; }
void p(std::string arg) { std::cout << "string " << arg << std::endl; }
void p(int arg1, int arg2) { std::cout<<"int/int "<<arg1<<arg2<<std::endl; }
void p(int arg1, std::string arg2) { std::cout<<"int/string "<<arg1<<arg2<<std::endl; }

class foo {
public:
template <typename... Args>
foo(Args... args): func{[args...](){ p(args()...); }} {}

void operator()() { func(); }

private:
std::function<void()> func;
};

int main() {
// create your objects...
foo i([]{return 1;});
foo s([]{return std::string("one");});
foo b([]{return 2;}, []{return std::string("two");});
// ... and use them later
i();
s();
b();
}

关于c++ - 可以接受未知签名的可变函数引用的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40942108/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com