简化存储在类的 std::vector 成员中的 std::函数的使用
Simplifying the use of std::function stored within a class's std::vector member
我已经编写了这个基类来将std::function<T>
存储在std::vector<T>
中,并且我有两个免费的函数模板foo()
和bar()
,它们都返回void
并将std::vector<T>
作为参数。目前,为了简单起见,他们做了完全相同的事情;但为了将来参考,他们将进行不同的计算或任务。到目前为止,这就是我所想到的:
#include <vector>
#include <functional
#include <iostream>
#include <exception>
template<typename T>
class MyClass {
private:
std::vector<std::function<void(std::vector<T>)>> myFuncs_;
public:
MyClass() = default;
void addFunc( std::function<void(std::vector<T>)> func ) {
myFuncs_.push_back(func);
}
std::function<void(std::vector<T>)> caller(unsigned idx) {
return myFuncs_.at(idx);
}
};
template<typename T>
void foo(std::vector<T> data) {
std::cout << "foo() called:n";
for (auto& d : data)
std::cout << d << " ";
std::cout << 'n';
}
template<typename T>
void bar(std::vector<T> data) {
std::cout << "bar() called:n";
for (auto& d : data)
std::cout << d << " ";
std::cout << 'n';
}
int main() {
try {
MyClass<int> myClass;
std::vector<int> a{ 1,3,5,7,9 };
std::vector<int> b{ 2,4,6,8,10 };
std::function<void(std::vector<int>)> funcA = std::bind(foo<int>, a);
std::function<void(std::vector<int>)> funcB = std::bind(bar<int>, b);
myClass.addFunc( funcA );
myClass.addFunc( funcB );
myClass.caller(0)(a);
myClass.caller(1)(b);
} catch( std::runtime_error& e ) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
这肯定会输出:
foo() called:
1 3 5 7 9
bar() called:
2 4 6 8 10
以下是我想知道的:是否有任何方法可以简化此代码;有些语法看起来是多余的,例如:在主函数中,在我实例化了类模板的一个实例并创建了一个具有值的std::vector
之后,我使用std::bind
创建了std::function<T>
的一个例子,然后我想将该函数添加到类的向量中。然后,在绑定它们并将它们添加到类的容器中之后,我在这里调用类的函数,以使用std::functions
的operator()
对要调用的函数进行索引。然而,函数需要一个std::vector<T>
,所以我似乎多次传递这个vector<T>
,正如您从上面代码的这一部分中看到的那样。
// std::vector<T> being passed to std::bind
std::function<void(std::vector<int>)> funcA = std::bind(foo<int>,a);
myClass.addFunc( funcA );
myClass.caller(0)(a); // Again std::vector<T> being passed but to `std::function`'s operator because the stored function requires this parameter.
这可以简化吗?或者这只是std::function
和std::bind
如何工作的语义?如果这可以简化,是在类本身中进行,以使用户更容易,还是从用户端进行?
您使用std::bind
的方式不对,例如在中
std::function<void(std::vector<int>)> funcA = std::bind(foo<int>, a);
您已经将参数a
绑定到foo<int>
,这意味着无论传递给funcA
的参数是什么都不会生效,上面的内容相当于
std::function<void()> funcA = std::bind(foo<int>, a);
为了简化代码,如果你想坚持使用std::bind
,你可以在MyClass
上有一个呼叫接线员,它可以呼叫所有注册的std::function
:
template<typename T>
class MyClass {
private:
std::vector<std::function<void()>> myFuncs_;
public:
MyClass() = default;
template <class... F, std::enable_if_t<(sizeof...(F) > 0), bool> = true>
void addFunc(F&&... func) {
((myFuncs_.push_back(std::forward<F>(func))), ...);
}
void operator()() const {
for (auto& fn : myFuncs_) {
fn();
}
}
};
auto funcA = std::bind(foo<int>, a);
auto funcB = std::bind(bar<int>, b);
myClass.addFunc(funcA, funcB);
myClass();
使用同样的想法,您可以随时切换到lambdas。
相关文章:
- 使用std::函数映射对象方法
- 可组合的lambda/std::函数与std::可选
- 当使用透明的std函数对象时,我们还需要写空的尖括号吗
- std::函数常量正确性未遵循
- 具有变量Number of Arguments的std::函数的矢量
- 从类型std::函数传递变量失败,尽管调用方期望的类型完全相同
- 如何调用存储在指向"std::函数"的指针中的 lambda?
- C++ STD 函数运算符:有没有一种方法可以通过函数将一个向量映射到另一个向量上?
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 如何将类 1 的 std::函数绑定到类 2 的函数?
- 如何制作可以接受任何类型的参数的 std::函数和 lambda
- 如何将 STL 队列推送函数绑定到 std::函数?
- std::函数不起作用,但普通的旧函数指针可以 - 为什么?
- 获取 std::函数以推断按引用传递/按值传递
- std::bind 和 std::函数术语不值为接受 0 个参数?
- 从其存储的回调中删除 std::函数是否安全
- 创建 std::函数,它返回具有函数成员值的变量.分段错误
- 创建一个带有 lambda 的 std::函数,而不知道函数的参数
- std::函数的解释
- 在调用过程中删除 std::函数