c++ - 从C++模板特化那 "base"调用 "overrides"模板函数呢?

标签 c++ templates

问题:

有没有一种方法可以从 C++ 中的专用模板函数调用“基本”模板函数,子类可以在覆盖它们时访问父类的虚拟方法版本? (注意:我怀疑答案是“否”,但很想是错误的)

上下文:

我经常发现自己专门化模板函数只是因为特殊情况需要额外的预处理或后处理,而不是因为代码的“内脏”发生了变化。

举个例子:

通过继承,您可以执行以下操作:

struct base { 
    virtual void go() { printf("%p", this); }
};
struct foo : base { 
    virtual void go() { printf("this foo lives at "); base::go(); } 
};

...调用 foo::go() 将打印“this foo lives at

不过,有了模板:

template <typename T>
void go(T const &t) { printf("%p\n", &t); }

template <>
void go(foo const &f) { 
    printf("this foo lives at "); 
    ??? how to access "base" template ??? 
}

您可以通过分解出一堆小辅助函数并专门化它们而不是您真正关心的函数来以一种丑陋的方式解决这个问题:

template <typename T>
void _go_pre(T const &t) { /* do nothing */ }

template <typename T>
void _go_post(T const &t) { /* do nothing */ }

template <typename T>
void go(T const &t) { 
    _go_pre(t); /* just in case */
    printf("%p\n", &t); 
    _go_post(t); 
}

template<>
void _go_pre(foo const &t) { printf("this foo lives at "); }

...但这会使代码变得非常困惑,因为现在“基本”模板需要预测“子”特化可能覆盖它的所有方式,并且大多数类型将使用很少的这些钩子(Hook)(如果有的话)。困惑很快变得难以阅读和维护,因为这些 Hook 的原因在它们被定义的时候是未知的,你必须测试已使用/未使用的 Hook 的不同组合。

所有这些都与您在子类无法访问父类提供的原始版本的世界中使用虚方法覆盖时遇到的问题完全一样。

最佳答案

直接是不可能的。但是,您可以像这样使用更少(并且 IMO 不那么丑陋)的助手:

template <typename T>
void base_go(T const &t) { printf("%p\n", &t); }

template <typename T>
void go(T const &t) { base_go(t); }

template<>
void go(foo const &t) { printf("this foo lives at "); base_go(t); }

作为替代方案,您可以将 base_ 变体放入单独的命名空间,而不是给它们修改名称。

关于c++ - 从C++模板特化那 "base"调用 "overrides"模板函数呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16897984/

相关文章:

c++ - 缩小 unsigned int 到 short unsigned int 的转换

c++ - QTransform scale 和 boundingRect.size() 的关系

c++ - '...' 标记调用模板类的模板化方法之前的预期主表达式

c++ - 从可变参数模板容器类中给定可变参数调用传入和传出方法

c++ - 如何在编译时专门化大型模板函数中的一小部分

c++ - 带有模板参数的部分专用模板

c++ - 如何将C++异常处理程序与C库完美结合?

c++ - 以 const 和 const 结尾的 getter 之间的区别

c# - 在 C# 中继承泛型的一个很好的理由

c++ - codeblocks c++ 停止工作可能是由于引用