【问题标题】:Changing type signature of base class member based on inheriting class template基于继承类模板改变基类成员的类型签名
【发布时间】:2015-02-18 06:47:15
【问题描述】:

我有两个类,一个继承自另一个:

struct A {
    (pure?) virtual tt returns_something();
}

template <typename T>
struct B : A {
    virtual T returns_something();
}

我该如何进行这项工作,以使 returns_something() 具有正确的类型签名。

我相信这是一个奇怪重复的模板模式的工作:

template <typename T>
struct A {
    pure virtual typename T::tt returns_something();
}
template <typename TT>
struct B : A<B<TT>> {
    typedef TT tt;
    virtual tt returns_something();
}

但是,这似乎抱怨“在 B 中没有名为 'tt' 的类型”(当我将 B 实例化为 TT 作为浮点数时)。

有什么想法吗?在这种情况下,这是正确的方法吗?还有其他更适合的方法吗?

注意:这是一个简化的情况。在同一类型 B 上模板化 A 只会使 A 有很多模板参数,我不希望这样。

【问题讨论】:

    标签: c++ templates inheritance crtp


    【解决方案1】:

    A&lt;B&lt;TT&gt;&gt;被实例化的时候,B&lt;TT&gt;还是一个不完整的类,所以不能使用B&lt;TT&gt;::tt

    如果有问题的类型是B 的模板参数,那么您可以通过特征类提取模板参数:

    template <typename TT>
    struct B;
    
    template<class> struct B_traits;
    template<class TT> 
    struct B_traits<B<TT>> {
        using tt = TT;
    };
    
    template <typename T>
    struct A {
       virtual typename B_traits<T>::tt returns_something();
    };
    

    Demo.

    【讨论】:

    • 谢谢!几个问题。有没有办法在没有“特征”类的情况下定义它? (重新排序定义或类似的东西)。另外,为什么要在定义 B_traits 之前立即声明 B_traits?
    • @AndrewSpott 1) 不是;由于B&lt;TT&gt; 派生自A&lt;B&lt;TT&gt;&gt;,因此您必须提取TTB&lt;TT&gt; 是不完整的类型;这需要使用单独的类(或同样烦人的东西)。 2)第一行是主模板B_traits的声明;第二个是B_traits 的部分特化,用于实际的Bs。
    猜你喜欢
    • 2021-08-09
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-03
    • 2010-10-23
    相关资源
    最近更新 更多