简体   繁体   English

C++ 专用模板继承自非专用版本

[英]C++ specialized template inherit from non-specialized version

I was trying to solve a problem, but found a different solution.我试图解决一个问题,但找到了不同的解决方案。 however out of curiosity like to know if the following is possible:但是出于好奇想知道以下是否可行:

template< class > struct S;
template< > struct S< Foo > : struct< Foo > {};

I would like to be able to inherit nonspecialized struct from specialized struct.the example above does not work because the inherited struct is the specialized, leading to the infinite recursion.我希望能够从专用结构继承非专用结构。上面的示例不起作用,因为继承的结构是专用结构,导致无限递归。

One possible solution was to add second template parameter, say bool specialized, such that the default is false, and specialized template has that parameter is true.however that makes things a bit messy since instantiation needs to specify additional parameter.一种可能的解决方案是添加第二个模板参数,比如 bool 专用,这样默认值为 false,专用模板的参数为 true。但是,由于实例化需要指定额外的参数,这让事情变得有点混乱。

Is there some other way around to implement the above?有没有其他方法可以实现上述内容?

the original problem was to implement matrix of matrixes, where matrix itself may have additional operators, depending if the constituent matrixes has those operators.I would hope that makes sense.最初的问题是实现矩阵矩阵,其中矩阵本身可能有额外的运算符,具体取决于组成矩阵是否具有这些运算符。我希望这是有道理的。 at the same time different specialized matrix need to be of the same base class at the same time retaining the same name, although with different template parameters.同时不同的专用矩阵需要属于相同的基类,同时保留相同的名称,尽管模板参数不同。 I have thought there might be a way to do it using enable_if and type traits我认为可能有一种方法可以使用 enable_if 和 type traits

You could keep all the generic stuff in a separate type, and extend that with your specialisation:您可以将所有通用内容保留在一个单独的类型中,并根据您的专业化对其进行扩展:

template <typename> struct S_generic { /* generic stuff here */ };

template <typename T> struct S : public S_generic<T> { /* nothing here */ };
template <> struct S<Foo> : public S_generic<Foo> { /* extra stuff here */ };

Edit : Alternatively, if you don't like the extra name, the way to use an extra flag without messiness when instantiating the template is to use a default value:编辑:或者,如果您不喜欢额外的名称,则在实例化模板时使用额外标志而不混乱的方法是使用默认值:

template <typename T, bool fully_defined=true> struct S;
template <typename T> struct S<T,false> { /* generic stuff here */ };

template <typename T> struct S<T,true> : public S<T,false> {};
template <> struct S<Foo,true> : public S<Foo,false> { /* extra stuff here */ };

One possible solution was to add second template parameter, say bool specialized, such that the default is false, and specialized template has that parameter is true.however that makes things a bit messy since instantiation needs to specify additional parameter.一种可能的解决方案是添加第二个模板参数,比如 bool 专用,这样默认值为 false,专用模板的参数为 true。但是,由于实例化需要指定额外的参数,这让事情变得有点混乱。

You can do template<class Foo, bool flag = false> , so the second parameter is optional.您可以执行template<class Foo, bool flag = false> ,因此第二个参数是可选的。

I like Mike Seymour's answer but you don't really have to specify true and false everywhere.我喜欢 Mike Seymour 的回答,但您不必在任何地方都指定真假。

You can have something like this:你可以有这样的事情:

template<class T, bool = false>
class Object {
    void abstract_method();
};

// Now for your derived specialized type do this

template<>
class Object<SpecialObject> : Object<SpecialObject, true> { 
    // override any methods
};

We only need to default the Object template class bool to false , then when we instantiate a Object<SpecialObject>() it now has assigned to it the full type which is Object<SpecialObject, false> so now all we need to do is tell the compiler to find a potential different specialization that matches Object<SpecialObject, true> and we do that after the : above.我们只需要默认Object模板类boolfalse ,然后当我们实例化Object<SpecialObject>()它现在已经分配给它完整的类型Object<SpecialObject, false>所以现在我们需要做的就是告诉编译器发现匹配的潜在不同的专业化Object<SpecialObject, true>和大家做了之后:以上。

Now the compiler will choose the class with the abstract_method in it, even though it was defaulted to false, we already have chosen that specialization with false because of that default parameter when the compiler first encountered the type Object<SpecialObject> it is really the same as Object<SpecialObject, false> , so now when we pass true we are explicitly saying I don't care who took use of that default false parameter now try to find a different specialization using true , and it works.现在编译器将选择其中包含abstract_method的类,即使它默认为 false,我们已经选择了带有false因为当编译器第一次遇到类型Object<SpecialObject>时,该默认参数实际上是相同的作为Object<SpecialObject, false> ,所以现在当我们传递true我们明确地说我不在乎谁使用了默认的false参数,现在尝试使用true找到不同的专业化,并且它有效。

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

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