Как хранить шаблонные объекты в контейнере STL и вызове функции-члена

Предположим, у вас есть класс, как

template<class T>
struct A {
void foo() {
// Need access to "T" here
typedef typename someTrait<T>::someType T2;
}
};

и вы хотели бы «зарегистрировать» (или сохранить) экземпляры класса (или указатели на него) с контейнером (возможно, STL) для последующего вызова foo() метод всех зарегистрированных экземпляров.

Поскольку экземпляры, созданные с различными параметрами шаблона, должны быть сохранены (A<int>, A<float>…) очевидно, никто не может использовать std::vector и хранить экземпляры или указатели на него. Что я могу представить, так это сделать метод static и сохранение указателей на функции void foo(), лайк:

 void static foo();

typedef void (* fooPtr)(void);
std::vector<fooPtr>

Но почему-то я чувствую, что это не очень C ++ 11-иш. Есть хорошее решение, которое вводит класс-обертку или что-то?

Введение базового класса и использование динамического приведения привели бы к зависимости от RTTI, право? Я хотел бы избежать зависимости от RTTI,

Как можно это сделать в C ++ 11? (Я не хотел бы вводить дополнительные зависимости, такие как ссылки на Boost или в зависимости от RTTI.)

Спасибо за ваше мнение!

3

Решение

Возможно, вы могли бы просто использовать виртуальные методы? Это работает и с C ++ 03.

struct ABase {
virtual void foo() = 0;
};

template<class T>
struct A : ABase {
virtual void foo() override {
// Access to "T" here
}
};

...

std::vector<std::unique_ptr<ABase>> vec;
vec.emplace_back(new A<int>());
vec.emplace_back(new A<float>());

for (auto& p_a : vec)
p_a->foo();
5

Другие решения

Если вам действительно нужен массив функций, вы можете использовать std::function в сочетании с std::bind

std::vector<std::function<void()> vec;
A<int> a;
vec.push_back(std::bind(&A<int>::foo, &a)); //now a should live at least as long, as vec
// or vec.push_back(std::bind(&A<int>::foo, a)); - now a will be _copied_ to vec

foo теперь функция memeber (std::bind ‘привязывает’ функцию к данной переменной здесь)

5

По вопросам рекламы [email protected]