【问题标题】:How to store templated objects in an STL container and member function call如何将模板化对象存储在 STL 容器和成员函数调用中
【发布时间】:2012-10-25 09:12:19
【问题描述】:

假设你有一个像

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

并且您想使用容器(可能是 STL)“注册”(或存储)类的实例(或指向它的指针),以便以后调用所有已注册实例的 foo() 方法。

由于要存储使用不同模板参数实例化的实例(A&lt;int&gt;A&lt;float&gt;、...),显然不能使用 std::vector 并存储实例或指向它的指针。我能想象的是制作方法static并将函数指针存储到void foo(),例如:

 void static foo();

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

但不知何故,我觉得这不是很 C++11 风格。有没有一个很好的解决方案来引入包装类或其他东西?

引入基类并使用动态转换会引入对RTTI 的依赖,对吧?我想避免依赖RTTI

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

感谢您的意见!

【问题讨论】:

  • Obviously one can't use a std::vector since the class is templated 是不正确的陈述。您需要对象向量还是函数指针向量?
  • 你是对的。那是一个草率的说法。我想我的意思是不同类型的 vector 由于不同的实例化类模板是不可能的。函数指针就够了。

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


【解决方案1】:

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

【讨论】:

  • 感谢您的回答!你能说几句你为什么选择unique_ptr吗?
  • @Frank:这样当向量超出范围时,可以正确释放实例。你也可以使用shared_ptr
  • 我认为虚函数是我一直在寻找的。它直接回答了如何存储模板化对象的问题。正确答案并为此 +1
  • @Frank,KennyTM,我已经问了这个问题的扩展here - 如果你也这样做了,请加入。
【解决方案2】:

如果你真的需要一个函数数组,你可以使用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 现在是一个成员函数(std::bind 在此处将函数“绑定”到给定变量)

【讨论】:

  • 请注意,如果vec 的寿命长于a,该函数将引用无效内容。您应该只使用 std::bind(&amp;A::foo, a) 或为第二个元素创建一个 shared_ptr。
  • 我认为std::bind(&amp;A::foo, &amp;a) 有问题。 A是类模板,需要模板参数。
  • 你可以用std::bind(&amp;A&lt;int&gt;::foo, &amp;a)修复它。
猜你喜欢
  • 2012-12-01
  • 2017-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-17
  • 2018-11-03
  • 1970-01-01
  • 2017-09-27
相关资源
最近更新 更多