C++ 如何将三个函数转换为一个泛型函数?
在下面的示例中,我有三个getColor函数 问题:如何将三个GetColor函数转换为一个通用函数C++ 如何将三个函数转换为一个泛型函数?,c++,templates,generics,C++,Templates,Generics,在下面的示例中,我有三个getColor函数 问题:如何将三个GetColor函数转换为一个通用函数 struct EcvColorMap{ vector<Scalar> getColors(){ vector<Scalar> result; //.... return result; } }; struct Scalar{ int val[3]; }; vector<Scalar>
struct EcvColorMap{
vector<Scalar> getColors(){
vector<Scalar> result;
//....
return result;
}
};
struct Scalar{
int val[3];
};
vector<Scalar> getColors(vector<Scalar> colors){
return colors;
}
vector<Scalar> getColors(Scalar color){
return{ color };
}
vector<Scalar> getColors(EcvColorMap color_map){
return color_map.getColors();
}
struct EcvColorMap{
向量getColors(){
矢量结果;
//....
返回结果;
}
};
结构标量{
int-val[3];
};
矢量颜色(矢量颜色){
返回颜色;
}
矢量颜色(标量颜色){
返回{color};
}
矢量GetColor(EcvColorMap颜色映射){
返回color_map.getColors();
}
问题是:函数体是不同的,如果您试图创建一个通用函数,而其他函数则部分专用,完全专用,如
template<typename T> vector<Scalar> getColors(T colors) {
return {colors};
}
//template<typename T> vector<Scalar> getColors(vector<T> colors) { // Not really necessary - see list initialization
// return colors;
//}
template<> vector<Scalar> getColors<EcvColorMap>(EcvColorMap colors) {
return colors.getColors();
}
模板向量getColors(T颜色){
返回{colors};
}
//模板向量getColors(向量颜色){//不是真的需要-请参阅列表初始化
//返回颜色;
//}
模板向量GetColor(EcvColorMap颜色){
返回colors.getColors();
}
您仍然需要为三个不同的模板编写代码,但毫无收获(编译时优势或代码重用在哪里?)
我个人的建议是:不要仅仅因为模板很酷就使用它,在实际需要时使用它们。在一个庞大的软件视图中,这是至关重要的。您发布的设计对我来说很有意义。正如Marco的回答所指出的,在这种情况下,您必须权衡使用模板的利弊 也就是说,你可以用特征来检查一个典型的方法;当您想抽象出可能以不同方式发生的事情时,通常会执行此操作。因此,您可以像这样分派实际的getter:
template<typename T>
vector<Scalar> getColors(T colors)
{
return getter<T>::get(colors);
}
模板
矢量颜色(T颜色)
{
返回getter::get(颜色);
}
然后你会为你的每个实体建立一些特征
template<typename T>
struct getter; // types not specified in your traits system will not work
template<>
struct getter<vector<Scalar>> {
static vector<Scalar> get(vector<Scalar> colors) {
return colors;
}
};
template<>
struct getter<Scalar> {
static vector<Scalar> get(Scalar color) {
return { color };
}
};
template<>
struct getter<EcvColorMap> {
static vector<Scalar> get(EcvColorMap color) {
return color_map.getColors();
}
};
模板
结构getter;//系统中未指定的类型将不起作用
模板
结构吸气剂{
静态矢量获取(矢量颜色){
返回颜色;
}
};
模板
结构吸气剂{
静态向量get(标量颜色){
返回{color};
}
};
模板
结构吸气剂{
静态向量get(EcvColorMap color){
返回color_map.getColors();
}
};
没有魔法,你仍然需要手工编写所有的代码唯一有效的情况是,如果您必须在更多的地方使用getter,那么您可以始终编写:
template<typename T>
void FunctionN(T arg)
{
auto val = getter<T>::get(arg);
// do stuff like printing etc
}
模板
无效函数n(T参数)
{
auto val=getter::get(arg);
//做印刷之类的事情
}
因此,N越大,从提取
get
操作中获得的收益就越多。类似地,set
操作也可以被除法等 您不需要转换这些函数,这一点非常清楚
这三个函数具有不同的主体,因此不能将它们放在单个模板函数中。您可以使用模板函数替换它们,并对这些类型进行专门化,但这只会使它变得复杂。前两个函数使用类型
标量和向量,这两个函数都可以用于构造向量。您可以将这些函数简化为一个函数,该函数支持可转换为标量
或向量
的任何类型
通过以上两项更改,您现在可以对问题中列出的所有类型调用getColors
std::vector<Scalar> colors;
Scalar color;
EcvColorMap colormap;
getColors(color);
getColors(colors);
getColors(colormap);
您可以创建一个通用函数并根据需要对其进行专门化,但这两个函数非常不同,您最好只使用三个函数。为什么要这样做?拥有这三个重载看起来是正确的设计。getColors(vector colors)
是不必要的,getColors(T colors)
处理从vector
@captainvious构建vector
的过程。没错,我需要更好地学习C++11,初始化列表也可以调用复制构造函数。
struct EcvColorMap
{
explicit operator std::vector<Scalar>() const
{
std::vector<Scalar> result;
//....
return result;
}
};
std::vector<Scalar> colors;
Scalar color;
EcvColorMap colormap;
getColors(color);
getColors(colors);
getColors(colormap);
std::vector<Scalar> colors;
Scalar color;
// Construct
std::vector<Scalar> new_colors1{color};
std::vector<Scalar> new_colors2{colors};
// Assign.
std::vector<Scalar> new_colors;
new_colors = colors;
new_colors = { color };
new_colors = colormap.getColors();