繁体   English   中英

如何通过 C++ 中模板化类型的子类传递模板化 function 参数?

[英]How to pass a templated function parameter with a subclass of the templated type in C++?

编译以下人为示例:

class Base
{};

class Derived : public Base
{};

template< typename T >
class A
{};

class B
{
public:

    static void f( const A< Base >& ) {}
};

int main()
{
    A< Base > tb;
    A< Derived > td;

    B::f( tb );
    B::f( td );

    return 0;
}

使用 g++-8 给我以下错误:

error: no matching function for call to 'B::f(A<Derived>&)'
 B::f( td );
note:   no known conversion for argument 1 from 'A<Derived>' to 'const A<Base>&'

为什么?

由于DerivedBase并且它不会覆盖Base的任何内容,为什么我不能在模板化的 function 参数中用Derived代替Base

Derived确实是从Base派生的,但这并不意味着A<Derived>因此必须从A<Base>派生。 C++ 模板不能以这种方式工作。

A<Derived>是一个 class,由A模板实例化。 你可以简单地声明:

class A_Derived {

     // ...

};

使用相同的成员(如果有的话),几乎得到了相同的结果。 A<Base>相同。 图片中没有其他内容,这两个班级绝对没有任何关系。 你可以在这里画一个心理图,好像你做了以下声明:

class A_Derived {

};

class A_Base {

};

这几乎就是历史。 您是否看到A_Derived在这里显式地从A_Base派生? 明显不是。 如果某些东西需要引用或指向A_Base的指针,则不能给它A_Derived ,因为这两个类彼此完全没有关系。 它们是独立的类。

PS如果您愿意,您可以将A<Derived>的显式特化声明为派生自A<Base> ,但特化是一个完全不同的主题......

模板实例,如A<Base>A<Derived> ,是不同的类型。 特别是它们没有任何 inheritance 关系,即使BaseDerived有关系。

有很多方法可以使您想要的工作。

首先,您可以使A<Derived>显式派生自A<Base> ,但这意味着添加整个 class 定义。

template<>
class A<Derived> : public A<Base>
{};

其次,您可以以构造函数模板的形式提供从A<Derived>A<Base>的隐式转换。 您可以使用std::enable_ifstd::is_base_of只允许A<T>其中T派生自Base ,或者如果您只想考虑这个特定的Derived类型,则可以直接使用std::is_same

template<typename T>
class A
{
    template<typename U, typename = std::enable_if_t<std::is_base_of_v<T, U>>>
    A(A<U> const& other);
};

第三,您可以以运算符模板的形式提供隐式转换,方式大致相同。

template<typename T>
class A
{
    template<typename U, typename = std::enable_if_t<std::is_base_of_v<U, T>>>
    operator U();
};

第四,你可以制作一个f模板并限制它需要什么类型。

template<typename T, typename = std::enable_if_t<std::is_base_of_v<Base, T>>>
static void f(A<T> const& a);

暂无
暂无

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

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