抱歉这个愚蠢的问题,但我对C ++很陌生。
我的项目中有一个名为AlertInfoBase
的基类。它有几十个子类。现在我想要一个类模板,它将有一个方法filter()
。此方法将始终返回对AlertInfoBase
的引用。这是代码:
template <class T>
class AlertInfoFilter
{
public:
AlertInfoFilter() { }
AlertInfoBase & filter(T & alertInfo)
{
return alertInfo;
}
};
如您所见,方法过滤器只返回传递的参数。我的目标是使用模板专门化创建filter()
的替代实现,但这不是我现在的问题/问题。
我面临的一件奇怪的事情是,当我将一个类的实例传递给filter()
时,它是AlertInfoBase
的子类,一切都按预期工作。它返回相同的引用,但是当我传递一个没有实现AlertInfoBase
的类的实例时,项目不会编译。实际上这是我想要的那种行为,但有些澄清为什么会发生这种情况会很好。编译器是否足够聪明,可以猜测由于返回类型而使用不正确的参数填充方法?
由于
P.S。我正在使用MinGW编译器。
答案 0 :(得分:5)
您可以将模板视为代码生成机制。模板的特定实例化在大多数方面与手动编写的代码相同,该代码仅在适当时替换模板参数。在您的示例中,如果您使用AlertInfoFilter
实例化std::string
(作为不从AlertInfoBase继承的类的示例),则会生成以下代码(大约):
class AlertInfoFilter_string
{
public:
AlertInfoFilter_string() { }
AlertInfoBase & filter(std::string & alertInfo)
{
return alertInfo;
}
};
显然,这不应该编译。
答案 1 :(得分:4)
是的,编译器非常聪明,知道这一点。当T从AlertInfoBase
下降并且在其他情况下无法将T
转换为返回类型时,它使用从子类到基类的隐式转换。
它也适用于在不相关的类中实现operator AlertInfoBase&
的类,但这会增加混乱,所以我不建议。
答案 2 :(得分:0)
filter
将T
作为输入并将其转换为AlertInfoBase
。如果T
现在是不属于AlertInfoBase
的子类的类型,并且不提供转换,则无法编译该程序。
答案 3 :(得分:0)
实际上,编译器会在接近代码时执行某些操作,将T替换为实际参数并编译模板。对于您在程序中使用的每个不同的T,都会发生一次。
当你通过例如。一个int
,你得到:
class AlertInfoFilter
{
public:
AlertInfoFilter() { }
AlertInfoBase & filter(int & alertInfo)
{
return alertInfo;
}
};
显然无法编译。