[英]c++ return template function
我有这种功能:
type uniRndtype()
{
return typeValue;
}
现在我试图将它们包装在另一个模板函数中,如下所示:
template<typename T>
T(* uniRndType(void))()
{
if (is_same<T, bool>::value)
{
return uniRndBool;
} else if (is_same<T, char>::value)
{
return uniRndChar;
} else
...
}
并这样称呼它:
uniRndType<int>();
但是我遇到一个错误: “错误:返回值类型与函数类型不匹配”,因为每个返回都具有不同的类型。
我有办法使其工作吗? 因为从运行时的角度来看,我看不到任何错误,所以只有编译器才有问题。
问题在于,尽管优化器可以消除无效的代码分支,但前端(词法,句法和语义分析)却无法。 这意味着模板实例中的所有代码都必须有效。 也就是说,即使在此情况下:
if (is_same<T, bool>::value)
{
return uniRndBool;
}
当T
为char
,body将永远不会执行,它仍然必须是有效的C ++代码。 当然不是,因为uniRndBool
没有正确的类型。
您有两种选择:一种在您的特定情况下有效的朴拙的选择,另一种是通用的。
拙劣的做法是在所有return
语句中使用reinterpret_cast<T(*)()>
。 对于正确的T
分支,将不进行操作。 其他分支永远不会在运行时执行,因此一切都会好起来的。
另一种解决方案是使用模板专门化。 由于专门设计函数模板不是一个好主意 ,因此可以使用众所周知的“委托给类”技巧:
template <class T>
struct uniRndTypeHelper;
template <>
struct uniRndTypeHelper<bool>
{
static bool (*get())() { return uniRndBool; }
};
template <>
struct uniRndTypeHelper<char>
{
static char (*get())() { return uniRndChar; }
};
template<typename T>
T(* uniRndType(void))()
{
return uniRndTypeHelper<T>::get();
}
template <typename T> T (*uniRndType())()
{
//else
...
}
template <> bool (*uniRndType())()
{
return uniRndBool;
}
template <> char (*uniRndType())()
{
return uniRndChar;
}
就这样。
编辑:原则上,我们必须像@Angew。 但是有点麻烦
这是行不通的,因为当编译器将模板方法扩展为给定类型时,该方法必须有效。 您的类型T必须与列出的所有返回类型兼容,例如bool
, char
等。正如我在评论中所提到的,如果您传入了std::string
您不会期望该方法起作用,您?
解决此问题的一种方法是使用模板特化指示每种类型的需求。
编译器需要知道在编译时函数/方法将使用哪种类型。 此时,您必须使用可以作为模板参数接收的类型实例化此模板函数,例如@ikh在此处编写的。
但是,如果将模板类与模板方法一起使用,则有两种方法:
1)只需将每个模板方法的实现写在.h文件中(就在声明模板类主体的位置),而不是仅使用原型;
2)或在.h文件中声明原型后,您需要使用可能会收到的模板参数来实例化此模板类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.