Предположим, у вас есть класс, как
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
.)
Спасибо за ваше мнение!
Возможно, вы могли бы просто использовать виртуальные методы? Это работает и с 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();
Если вам действительно нужен массив функций, вы можете использовать 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
‘привязывает’ функцию к данной переменной здесь)