Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;继承模板可靠类型_C++_Templates_Inheritance_Using - Fatal编程技术网

C++ C++;继承模板可靠类型

C++ C++;继承模板可靠类型,c++,templates,inheritance,using,C++,Templates,Inheritance,Using,我有一个模板和许多派生类。在所有这些类中,我想使用模板类型和它的一些依赖类型(实际上我有许多类型和许多依赖类型) 以下方法非常糟糕,因为我需要手动继承(使用关键字)父类中的所有类型(请参见代码示例): 编辑:我不知道我要使用类型的类也是模板这一点很重要。我相应地更新了代码示例 template<class T> class A { using TBase = T; using TDerived = T[10]; } template<class T> class

我有一个模板和许多派生类。在所有这些类中,我想使用模板类型和它的一些依赖类型(实际上我有许多类型和许多依赖类型)

以下方法非常糟糕,因为我需要手动继承(使用关键字)父类中的所有类型(请参见代码示例):

编辑:我不知道我要使用类型的类也是模板这一点很重要。我相应地更新了代码示例

template<class T>
class A {
  using TBase = T;
  using TDerived = T[10];
}

template<class T>
class B : A<T> {
  // NOTE i want the types TBase and TDerived here and in further children
  using TBase    = A<T>::TBase;
  using TDerived = A<T>::TDerived
}

class C : B<int> {
  // NOTE i want the types TBase and TDerived here and in further children
  using TBase    = B<int>::TBase;
  using TDerived = B<int>::TDerived
}
解决方案2:特质类
(基于Oguk的回答)

  • 使用模板化特征类而不是名称空间
    这提供了几乎相同的功能
  • 类型信息的不同可用性
    我以前没有想到的一件事是检查哪些类型信息在哪里可用,以及是否需要更多的字符来从父类检索所需的类型信息(请参见注释)
  • 见下面的代码:

    template<class T>
    struct TypesContainer {
      using TBase = T;
      using TDerived = T[10];
    };
    
    template<class T>
    class A {
    public:
      // TODO possible to directly inherit all types?
      //using TypesContainer<T>;
    
      // NOTE this is only possible for methods, not types
      using Types = TypesContainer<T>;
      typename Types::TBase memberA;
    };
    
    class B : public A<int> {
    public:
      // NOTE here I have all template information via definition (by hand)
      using Types = TypesContainer<int>;
      typename Types::TBase memberB;
    };
    
    class C : public B {
    public:
      // NOTE here I don't have the type information any more
      using Types = TypesContainer<A::Types::TBase>;
      typename Types::TBase memberC;
    };
    
    模板
    结构类型容器{
    使用TBase=T;
    使用TDerived=T[10];
    };
    模板
    甲级{
    公众:
    //是否可以直接继承所有类型?
    //使用字体容器;
    //注意,这仅适用于方法,而不适用于类型
    使用类型=类型容器;
    typename类型::TBase memberA;
    };
    B类:公共A{
    公众:
    //注意这里我有所有的模板信息通过定义(手工)
    使用类型=类型容器;
    typename类型::TBase memberB;
    };
    丙类:公共乙类{
    公众:
    //注意这里我没有更多的类型信息
    使用类型=类型容器;
    typename类型::TBase memberC;
    };
    
    问题:

    是否有一种方法可以直接继承类范围内命名空间/类的所有成员(请参见TODO注释)。使用
    不带赋值的关键字
    =
    只适用于方法,而不适用于名称空间、类和类型

    首先,如果您对自己的设计还满意,那么如果您公开继承基类,它应该可以工作。这将在您发布的代码中起作用。但是,如果您的示例非常简化,那么可能还有另一个原因导致您无法在实际代码中访问typedef:可能会给您带来问题的是,您的派生类实际上也是一个带有类型参数
    T
    的模板类,例如
    B
    。这将使基类
    A
    依赖,如果在
    B
    中使用非依赖名称(即仅
    TBase
    )引用它们,则在查找过程中不会考虑其成员,因此不会找到它们。将它们称为
    typename A::TBase
    可以通过使名称依赖于名称来解决这个问题

    如果您想遵循您的另一个想法,并在类之外提供该类型信息(因为它在概念上更多地连接到
    T
    ,而不是类
    A
    ),而不是您所想到的“模板化名称空间”,通常,特征类用于此目的:

    template <class T>
    struct MyTraits {
        using TBase = T;
        using TDerived = T[10];
    }
    
    模板
    结构特征{
    使用TBase=T;
    使用TDerived=T[10];
    }
    

    然后,您可以使用
    声明(或者,
    typedefs
    )从任何地方使用MyTraits::TBase访问这些
    。这是使用模板化名称空间可以有效实现的。如果在依赖上下文中使用
    MyTraits
    的using/typedef成员,也就是
    typename MyTraits::TBase

    类B继承TBase并自动派生,则不要忘记添加
    typename
    关键字,您无需执行任何操作。但是如果您私下继承
    A
    ,则它们是私有的,因此后代无法看到它们;您需要公开继承(如果愿意,您也可以继承protected,但我不确定这是否有意义)。请注意,如果class
    B
    是一个模板,并且基依赖于参数,则必须限定继承的类型。但是IIRC用
    B::
    对他们进行限定应该行得通。@JanHudec谢谢你的回答。很抱歉,由于我没有足够的声誉,我无法对它们进行投票:(
    使用
    肯定适用于类型。@JanHudec我的意思是使用它时不带等号,就像在解决方案2中我的TODO注释之后一样(
    使用TypesContainer;
    )。这样做(有或没有
    类型名
    )导致编译器错误:应为嵌套名称说明符!
    template <class T>
    struct MyTraits {
        using TBase = T;
        using TDerived = T[10];
    }