是否可以将调用站点上对象的静态类型用作其模板方法的自动推导的模板参数

Is it possible to use the static type of an object on call site as an automatically deduced template argument to its template method?

本文关键字:模板方法 参数 类型 调用 站点 静态类 静态 对象 是否      更新时间:2023-10-16

模板方法允许为不同静态类型的参数跨一组方法实例。自动参数推导避免了信息的重复。

我们面临这样一种情况:我们希望自动推断作为模板实参的静态类型是类实例本身的类型。(在调用现场,实例的类型可以是比声明模板方法的类更专门化的类型。)

class Base
{
public:
    template <class T_callingObject>
    T_callingObject foo()
    {
        bar += 1;
        // We have a strong guarantee on this cast only if T_callingObject
        // is automatically deduced !
        return static_cast<T_callingObject&>(*this);
    }
private:
    int bar;
};
class Derived : public Base
{
};
int main()
{
    Base base;
    Derived derived;
    base = base.foo<Base>();           // we already know the type of base is Base
    derived = derived.foo<Derived>();  // idem
}

问题是:有没有办法不重复basederived的类型?

编辑: Base上的CRTP在这里不是一个选项,我们需要有一个共同的祖先类型

这通常通过CRTP(奇怪递归模板模式)通过使Base本身成为模板来解决:

template <typename D>
struct Base {
    D& foo() { return static_cast<D&>(*this); }
};

struct Derived: Base<Derived>

您可以对D参数进行的操作集是受限制的(在Base<Derived>实例化时是一个不完整的时间),但在您的简单情况下,这是可行的。

您仍然会怀疑是否有人不会无意中写struct Bar: Base<Foo>,所以只有减少了的问题表面。

EDIT:如果Base的CRTP不被允许(这种情况经常发生),您可以分层抽象:

struct Base { virtual ~Base() {} };
template <typename D>
struct BaseT: Base {
    D& foo() { return static_cast<D&>(*this); }
};
struct Derived: BaseT<Derived> {};

因为一般情况下如果foo需要知道D是什么,你不再有一个单一的统一类型