繁体   English   中英

如果存在CRTP,如何在派生的情况下调用函数,否则使用默认值?

[英]How to call function in derived if exists else use a default if using CRTP?

对于使用CRTP的某些结构,我有一个辅助基类,以帮助我获取有关它们的一些信息:

template <class T>
struct MyHelper
{
    size_t size() const { return sizeof(T); }
};

我已经在代码库的各种库中使用了使用此结构定义的结构,我想有一种方法来记录它们。 我的第一个想法是这样的:

template <class T>
struct MyHelper
{
    size_t size() const { return sizeof(T); }
    virtual void print(std::ostream& out) const { out << "(" << sizeof(T) << ")"; }
};

但是后来我意识到,由于几个原因,该方法行不通-其中之一是添加虚拟,实际上改变了大小,而不仅仅是POD数据。

没有虚拟关键字,是否有办法让我拥有使用上述实现的默认toStr方法,除非特定的派生类T具有在这种情况下适合的实现?

我认为,执行此类操作的最直接方法是将派遣到派生类可以根据需要隐藏的其他非虚函数。 例如:

template <class T>
struct MyHelper
{
  size_t size() const { return sizeof(T); }

  void print(std::ostream &out) const {
    // Cast to derived, call do_print. This will be derived's do_print
    // if it exists and MyHelper's otherwise.
    static_cast<T const*>(this)->do_print(out);
  }

  void do_print(std::ostream& out) const {
    out << "(" << sizeof(T) << ")";
  }
};


struct A : MyHelper<A> {
  // no do_print, so MyHelper<A>'s will be used
  int x;
};

struct B : MyHelper<B> {
  // B's do_print is found and used in MyHelper<B>::print
  void do_print(std::ostream &out) const {
    out << "Hello!\n";
  }
};

template<typename T>
void foo(MyHelper<T> const &r) {
  r.print(std::cout);
}

int main() {
  A a;
  B b;

  foo(a);
  foo(b);
}

输出:

(4)Hello!

您可能还可以使用SFINAE构建不需要第二个成员函数的东西,但是我怀疑增加的复杂性是否值得。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM