【问题标题】:Define multiple methods with parameters from variadic templates使用可变参数模板定义多个方法
【发布时间】:2012-03-09 20:06:09
【问题描述】:

我想以某种方式定义一个基本模板类,以便它接受可变模板参数并为每个参数定义一个虚拟方法,其中参数是参数类型。

例如Base<int, bool, string> 应该给我 3 个虚拟方法:Foo(int)Foo(bool)Foo(string)

我尝试了以下方法:

template <typename Param>
struct BaseSingle
{
    virtual void Foo(Param) {};
};

template <typename... Params>
struct Base : public BaseSingle<Params>...
{
};

不幸的是,Foo 变得模棱两可。我无法让using BaseSingle&lt;Params&gt;::Foo... 语法工作。有什么办法吗?

我知道,或者,我可以递归地从 BaseSingle 继承并传入剩余的参数。是否有性能影响?

【问题讨论】:

  • 递归继承是正常的,例如std::tuple 就是这样实现的。我不明白为什么你会受到性能影响,你的函数甚至不会相互覆盖,也不会在运行时调用被覆盖的成员传递参数。
  • 一些实现std::tuple使用递归继承。但好人没有。 ;-)

标签: c++ c++11 variadic-templates


【解决方案1】:

这是一个需要精确类型匹配的建议:

#include <utility>
#include <typeinfo>
#include <string>
#include <iostream>
#include <cstdlib>
#include <memory>

#include <cxxabi.h>

using namespace std;

// GCC demangling -- not required for functionality
string demangle(const char* mangled) {
  int status;
  unique_ptr<char[], void (*)(void*)> result(
    abi::__cxa_demangle(mangled, 0, 0, &status), free);
  return result.get() ? string(result.get()) : "ERROR";
}

template<typename Param>
struct BaseSingle {
  virtual void BaseFoo(Param) {
    cout << "Hello from BaseSingle<"
         << demangle(typeid(Param).name())
         << ">::BaseFoo" << endl;
  };
};

template<typename... Params>
struct Base : public BaseSingle<Params>... {
  template<typename T> void Foo(T&& x) {
    this->BaseSingle<T>::BaseFoo(forward<T>(x));
  }
};

int main() {
  Base<string, int, bool> b;
  b.Foo(1);
  b.Foo(true);
  b.Foo(string("ab"));
}

但是 IMO 你自己的使用递归继承的建议听起来更优雅。

【讨论】:

  • 你需要一个std::make_unique 设施:) +1 来解决demangle 中的混乱局面。有趣的东西
  • 我试过这个,并让Derived 继承自Base。似乎this-&gt;BaseSingle&lt;T&gt;::BaseFoo 没有调用被覆盖的Derived Foo,而是调用了基类,这就是这个虚函数业务的重点。
  • @MTsoul 只需将其重写为 BaseSingle&lt;T&gt;* base = this; base-&gt;BaseFoo(forward&lt;T&gt;(x)); 即可恢复您的虚拟调度
猜你喜欢
  • 2021-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
  • 2016-12-01
  • 2013-04-16
  • 2015-07-11
相关资源
最近更新 更多