从部分专用模板类创建对象

时间:2013-03-03 18:35:26

标签: c++ templates c++11

如何创建标记为WRONG的对象?它是一个部分专用模板类。

template<typename C, typename size_type = unsigned short>
struct MatrixDataRect {...};

template<typename T, size_t H, size_t W>
class MatrixDataRect<std::array<T,H*W>, size_t> {...};

int main()
{
    MatrixDataRect<std::vector<double>> mat_data_vector;
    MatrixDataRect<std::array<double,10*5>> mat_data_array; // WRONG!!!!
    return 0;
}

这是错误的,因为WRONG行使用第一个模板类。不是第二个。 因为编译器不能分别为H和W分配10 * 5。

2 个答案:

答案 0 :(得分:4)

template<typename T, size_t H, size_t W>
class MatrixDataRect<std::array<T,H*W>, size_t> {...};
MatrixDataRect<std::array<double,10*5>> mat_data_array;

问题是模板参数H和W不能从调用地推断出来。基本上,在实例化期间,copiler将乘以5*10以生成50,然后尝试实例化std::array<double,50>,然后使用实例化类型来实例化MatrixDataRect<std::array<double,50>>。此时,无法确定H的{​​{1}}和W的值是多少({1}}(5和10?,10和5?,25和2?)。 ..)

由于无法应用类型推导,编译器将回退到非专用版本并实例化主模板。

您可以使用的替代方法是:使专业化采用MatrixDataRect和单一大小参数(作为主模板)。这适用于问题中的所有代码,如果您需要这两个维度,则可能不适用于其他成员。更改模板,以便明确传递大小。

答案 1 :(得分:2)

有两个问题:

  1. 10*5被评估为50,然后编译器尝试推导出H*W,这是无法完成的。它们可以是任何size_t值乘以50。

  2. 您专门将size_t作为第二个模板参数,必须在实例化时给出,因为它无法推断出来。否则,您只是实例化MatrixDataRect<std::array<double,10*5>, unsigned short>

  3. 以下方法可行:

    template<typename C, typename size_type = unsigned short>
    struct MatrixDataRect {...};
    
    template<typename T, size_t S>
    class MatrixDataRect<std::array<T,S>, size_t> {...};
    
    int main()
    {
        MatrixDataRect<std::vector<double>> mat_data_vector;
        MatrixDataRect<std::array<double,10*5>, size_t> mat_data_array;
        return 0;
    }