Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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 - Fatal编程技术网

C++ C+中的继承和模板+;

C++ C+中的继承和模板+;,c++,templates,inheritance,C++,Templates,Inheritance,我在继承和模板方面有以下问题: class Base {}; class Deriv : public Base {}; template <class T> class X{}; void f(X<Base>& inst) {} int main() { X<Base> xb; f(xb); X<Deriv> xd; f(xd); return 0; } template<class T> void

我在继承和模板方面有以下问题:

class Base {};
class Deriv : public Base {};

template <class T> class X{};

void f(X<Base>& inst) {}

int main()
{
  X<Base> xb;
  f(xb);
  X<Deriv> xd;
  f(xd);
  return 0;
}
template<class T>
void f(X<T>& inst) {}
类基{};
类Deriv:公共基{};
模板类X{};
void f(X&inst){}
int main()
{
xxB;
f(xb);
xxd;
f(xd);
返回0;
}

程序未编译,因为
X
X
之间没有关系。尽管如此,我认为使用
X
以及
X
可以做的一切都应该是可能的。除了将
f
的函数体复制到一个新函数
void g(X&inst)
,我还能做些什么吗?

如果您需要这样的功能,那么您必须按照您所说的在类型或重载上设置模板。或者,您可以明确地专门化
X
,这样
X:X

为什么您认为它们应该相关?考虑以下事项:

template<typename T>
class X;

template<>
class X<Base> {
    int x;
};

template<>
class X<Deriv> {
    double d;
};

您可以继续使用模板:

class Base {};
class Deriv : public Base {};

template <class T> class X{};

void f(X<Base>& inst) {}

int main()
{
  X<Base> xb;
  f(xb);
  X<Deriv> xd;
  f(xd);
  return 0;
}
template<class T>
void f(X<T>& inst) {}
模板
void f(X&inst){}
适用于
X
X


编译器可能会复制代码(如果它不够聪明),但您不必这样做。

这取决于具体情况。考虑代码< > x>代码> <代码> STD::SysDypPTR<代码>的情况。如果
std::shared_ptr
是从
std::shared_ptr
派生的,则会破坏类型安全性,但会有一个隐式值转换

但是,由于您是通过引用传递给non-
const
,这样的值转换不会直接帮助您


其他可能性包括从公共接口继承和模板化函数。

模板的不同实例化是不相关的类型,即使实例化模板参数是相关的。也就是说,
X
X
无关,无论
A
B
之间的关系如何

现在,我们可以做些什么,这取决于您的模板实际是什么。在某些情况下,您可以提供转换,以便针对特定操作将
X
转换为
X
。另一种选择是修改函数,使其能够接受从
Base
派生的
X
(这可以通过创建一个模板并使用SFINAE来禁止使用不是从
Base
派生的
T
s调用它来实现。同样,根据模板的不同,您可能能够提供对底层类型的访问,在这种情况下,函数可以引用
Base
(使用
.get()
方法考虑
shared\u ptr
unique\u ptr


如果没有对您实际想要完成的内容的描述,就不可能提供一个好的替代方案。

您能告诉我如何更改代码以专门化类并使所有内容正常工作吗?编译器将复制代码。如果函数是内联的,则通过内联,如果不是,则必须生成两个实例化如果没有人查看(不比较地址),则为ons(专门化的地址必须不同)编译器可以作弊。无论如何,主要的一点是OP没有创建多个函数,编译器可以为他做。好吧,在这种情况下,
X
中没有任何东西不在
X
中,两者之间唯一的区别是
Deriv
Base
之间的区别是的,
hfhc2是的,
x
x
中,而不在
x
中,
d
不在
x
中,但在
x
中。区别不仅仅是类型参数。这不是我的意思。在我的程序中,我使用了一个boost图,它具有类型
邻接列表
,其中属性是类一些参数。但是,在一个函数中,我需要一个具有不同属性的图,这些属性是原始属性的派生类。否则,graph类不会更改,我看不出有什么理由不起作用。@hfhc2这正是C++类型系统的工作方式。不同的类是不同的类,句号。您可以想到
 X
X
就像
A
B
一样。它们之间没有任何关联,使用不同类型的模板会创建完全不同且不兼容的类。它们就像您使用
类A{};类B{}一样不同;
我突然想到,在Java中,我会基于泛型编写函数,强制执行模板参数是一个扩展
Base
XWell的类,接口应该是
Base
,如果我将
X
传递给
f
我希望将其视为
X
@hfh的实例c2:用我自己的话来说,那“会破坏类型安全”。一般来说。