2

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

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 行使用第一个模板类。不是第二个。因为编译器不能将 10*5 分别分配给 H 和 W。

4

2 回答 2

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 不能从调用位置推导出来。基本上,在实例化过程中,编译器会乘以5*10yield50然后尝试实例化std::array<double,50>,实例化的类型然后用于实例化MatrixDataRect<std::array<double,50>>。在这一点上,不可能弄清楚H和的值W是什么MatrixDataRect(是 5 和 10?,10 和 5?,25 和 2?...)

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

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

于 2013-03-03T18:40:05.453 回答
2

有两个问题:

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

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

以下将起作用:

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;
}
于 2013-03-03T18:43:00.803 回答