C++ 为一组类型专门化许多模板

C++ 为一组类型专门化许多模板,c++,templates,template-specialization,C++,Templates,Template Specialization,如何为各种标量值专门化多个模板?(例如int,float,size\u t,uint32\u t,以及stdint标题中定义的类型) 我可以避免为每种类型专门化每个模板吗? 如果可能的话,我不想使用boost或其他非标准库 以下是一些解决方案: 用多个函数替换每个模板。每个标量类型一个函数。(但是有很多模板。这意味着要编写很多函数。) 如果模板采用非标量类型,则失败。(但我还想为数组类型编写模板。这意味着我需要更改函数的名称。一组用于标量计算的函数名称。另一组用于标量矩阵计算。还有一组用于矩阵矩

如何为各种标量值专门化多个模板?(例如
int
float
size\u t
uint32\u t
,以及
stdint
标题中定义的类型)

我可以避免为每种类型专门化每个模板吗? 如果可能的话,我不想使用boost或其他非标准库

以下是一些解决方案:

  • 用多个函数替换每个模板。每个标量类型一个函数。(但是有很多模板。这意味着要编写很多函数。)

  • 如果模板采用非标量类型,则失败。(但我还想为数组类型编写模板。这意味着我需要更改函数的名称。一组用于标量计算的函数名称。另一组用于标量矩阵计算。还有一组用于矩阵矩阵计算。如果我试图重载运算符,我想这不会起作用。)

  • Nawaz的元编程解决方案。与此案例的解决方案2中的问题相同

  • 专门化每个标量类型的泛型模板。例如,write
    inline long getRatio
    inline long getRatio
    等都可以工作,但对于许多模板都需要这样做

  • 再次感谢

    范例 (这使用Andrew的解决方案。适用于旧的std库。仍然需要c++11。使用英特尔icc编译-std=c++11):

    #定义标准普尔曼标准门
    命名空间stdpoor{
    模板
    如果{},结构启用};
    模板
    如果{typedef t type;},则结构启用;
    模板
    结构积分常数{
    静态constexpr T值=v;
    类型定义T值_类型;
    typedef积分_常数型;
    constexpr运算符值\u type()const{
    无异常返回值;
    }
    constexpr value_type运算符()()const{
    无异常返回值;
    }
    };
    typedef积分\常数真\类型;
    typedef积分_常数假_类型;
    }
    模板
    类SimpleArray;
    模板
    结构是标量:STD_POORMAN::false_type{};
    //支持的标量类型的专门化:
    模板结构是标量:STD_POORMAN::true_type{};
    模板结构是标量:STD_POORMAN::true_type{};
    模板结构是标量:STD_POORMAN::true_type{};
    模板结构是标量:STD_POORMAN::true_type{};
    模板结构是标量:STD_POORMAN::true_type{};
    模板
    类SimpleArray{
    公众:
    T*ar_data;//指向数据的指针
    数组中的int size;/#元素
    SimpleArray(T*in\u-ar\u数据,int-in\u大小){
    ar_数据=in_ar_数据;
    大小=英寸大小;
    };
    模板
    void运算符+=(常量SimpleArray&B){
    //阵列+=
    int i;
    对于(i=0;i
    如果您试图仅为某些类型实现此模板,则可以在.cpp文件中声明它们,类似如下:


    如果您希望在此模板中允许任何内容,但明确声明某些类型,此链接可能会有所帮助:

    根据对问题的评论中的讨论,将其浓缩为一个较小的示例,您有一个类型
    矩阵
    ,您希望实现,比如说,
    运算符+=
    。此运算符的行为因操作数是标量还是其他矩阵而异

    因此,您希望提供两个专业;一个用于矩阵标量运算,一个用于矩阵运算。在这些类型中,您希望接受任何有效的标量类型或任何有效的矩阵类型

    这是一个用于和使用的经典用例。定义特征
    为标量

    // Base template:
    template <typename T>
    struct is_scalar : std::false_type {};
    
    // Specialisations for supported scalar types:
    template <> struct is_scalar<int> : std::true_type {};
    template <> struct is_scalar<float> : std::true_type {};
    template <> struct is_scalar<double> : std::true_type {};
    // etc.
    
    然后,您的运算符将成为表单的(成员)函数模板:

    template <typename T>
    std::enable_if_t<is_scalar<T>::value, Matrix&> operator+=(const T& rhs) {
      // Implementation for addition of scalar to matrix
    }
    
    template <typename T>
    std::enable_if_t<is_matrix<T>::value, Matrix&> operator+=(const T& rhs) {
      // Implementation for addition of matrix to matrix
    }
    
    模板
    std::启用_if_t运算符+=(常量t和rhs){
    //矩阵标量加法的实现
    }
    模板
    std::启用_if_t运算符+=(常量t和rhs){
    //矩阵与矩阵相加的实现
    }
    

    请注意,标准库已经为您提供了!剩下的就是为您支持的任何矩阵类型定义
    is_matrix
    专业化。

    您要解决的具体问题是什么?这是一个非常广泛的问题。我同意巴里的要求,提出一个更狭隘的问题陈述。不清楚的是,您是否希望简单地允许许多模板用于您确定为“标量类型”的任何内容,对于这些内容,SFINAE和适当的特征就足够了,或者您是否需要这些专门知识来包含与
    float
    相比的
    int
    不同的代码(例如)。一个具体的例子可能会产生更有针对性的建议。为数组操作编写一个小型库,类似于python的numpy库。现在,我想为标量类型的计算专门化每个模板(例如运算符*=,+=等),并且能够为所有矩阵类型专门化模板(int矩阵,float矩阵等)。那么让我再加一个例子。你是说“专业化”还是“启用”?专业化意味着您希望
    浮点
    的实现与
    int
    不同,例如
    运算符+=
    。启用仅意味着您允许
    float
    int
    (或任何其他标识的“标量类型”)实例化,但不允许
    Matrix
    std::string
    (或任何未标识为“标量类型”)实例化。这听起来像是你想要的,但希望这个例子能增加更多的清晰度
    // Base template:
    template <typename T>
    struct is_matrix : std::false_type {};
    
    // Specialisations:
    template<typename T>
    struct is_matrix<Matrix<T>> : std::true_type {};
    // and possibly others...
    
    template <typename T>
    std::enable_if_t<is_scalar<T>::value, Matrix&> operator+=(const T& rhs) {
      // Implementation for addition of scalar to matrix
    }
    
    template <typename T>
    std::enable_if_t<is_matrix<T>::value, Matrix&> operator+=(const T& rhs) {
      // Implementation for addition of matrix to matrix
    }