如何在STL容器和成员函数调用中存储模板化对象

时间:2012-10-25 09:12:20

标签: c++ templates stl c++11 member-function-pointers

假设您有类似

的类
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-ish。是否有一个很好的解决方案,它引入了一个包装类或什么?

引入基类并使用动态强制转换会在RTTI上引入依赖关系,对吧?我想避免依赖RTTI

如何在C ++ 11中做到这一点? (我不想引入其他依赖项,例如链接到Boost或依赖RTTI。)

感谢您的意见!

2 个答案:

答案 0 :(得分:5)

可能你只能使用虚拟方法?这也适用于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();

答案 1 :(得分:5)

如果您确实需要一系列功能,可以将std::functionstd::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'将函数绑定到给定变量)