Я написал этот базовый класс для хранения 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::function<T>
, используя std::bind
с функцией Iхочу затем добавить в вектор моего класса.Затем, связав их и добавив их в контейнер моего класса, я вызываю функцию класса для индексации функции, которую хочу вызвать, используя std::functions
's 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
?Если это можно упростить, будет ли это сделано внутри самого класса, чтобы облегчить его для пользователя, или это будет со стороны пользователя?