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++_Templates_Generics - Fatal编程技术网

C++ 如何将三个函数转换为一个泛型函数?

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>

在下面的示例中,我有三个getColor函数

问题:如何将三个GetColor函数转换为一个通用函数

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();