提问人:Gerson 提问时间:7/30/2023 更新时间:7/30/2023 访问量:111
如何使用自定义模板子类创建初始值设定项列表构造函数?
How to create a initializer list constructor using a custom template subclass?
问:
基本上,我想做的是能够使用如下所示的基元列表构造一个对象:
int main()
{
// C primitives initialization list
int matrix[2][2] = { { 1, 2 }, { 2, 3 }, };
// C++ stl class initialization list
std::string s = { 'f', 'o', 'o' '\0' };
// My custom 2x2 Matrix subclass
Matrix2<int> mat = { { 2, 0 }, { 6, 7 } }; // is it possible?
}
我尝试使用此线程中启发的声明,但没有成功
constexpr initializer_list() noexcept : _First(nullptr), _Last(nullptr) {}
template <class T, unsigned int M, unsigned int N> class Matrix {
// Matrix(initializer_list<T> &&lst) : _First(nullptr), _Last(nullptr) {} // (1) Does not work
Matrix(std::initializer_list<T> &&lst) { } // (2) no error on definition itself
}
template <class T> class Matrix2 : public SquareMatrix<T, 2> {};
(1):由于上面的 clang 错误而不起作用:clang: Member initializer '_First' does not name a non-static data member or base class [mem_init_not_member_or_class]
(2):由于构造和时的错误,也不起作用:Matrix
Matrix2
clang: Too few template arguments for class template 'Matrix' [template_arg_list_different_arity]
clang: No viable conversion from 'int' to 'Matrix<int, 2, 2>' [typecheck_nonviable_condition]
为了简化问题,我省略了主要代码,完整的代码可以在这里找到
答:
1赞
o_oTurtle
7/30/2023
#1
你可以把它编码为:std::initializer_list<std::initializer_list<T>>
template<typename T>
class Matrix2
{
public:
Matrix2(std::initializer_list<std::initializer_list<T>> list) {
if (list.size() > 2)
throw std::out_of_range{ "Too many rows." };
int rowNum = 0;
for (auto& row : list)
{
if(row.size() > 2)
throw std::out_of_range{ "Too many cols." };
int colNum = 0;
for (auto& ele : row)
mat[rowNum][colNum++] = ele;
rowNum++;
}
// for debug
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
std::cout << mat[i][j];
}
private:
T mat[2][2];
};
int main()
{
Matrix2 mat{ {1, 2}, {3, 4} };
return 0;
}
评论
0赞
Jarod42
7/30/2023
#2
{..}
没有类型,它不是.std::initializer_list
{..}
禁止除 C 阵列类型之外的大多数推导。std::initializer_list
std::initializer_list
最适用于“未知”大小。
对于 matrix2x2,C 数组似乎更合适(可以在编译时检查大小):
template <typename T>
class Matrix2
{
public:
Matrix2(const T (&ini)[2][2]) : mat{ini[0][0], ini[0][1], ini[1][0], ini[1][1]} {}
// ...
private:
T mat[2][2];
};
评论
0赞
Gerson
7/30/2023
一个问题是不是的成员,所以我不能在构造函数上使用成员初始化列表,必须访问使用,因为我想将它用于超类 anw 上的 MxN 矩阵。这有效:但这不是:由于:mat
Matrix
Matrix2
this->
Matrix
C++ const int arr[2][2] = {{2, 0}, {6, 7}}; Matrix2<int> a = arr;
Matrix2<int> a = {{2, 0}, {6, 7}};
error: could not convert ‘{{2, 0}, {6, 7}}’ from ‘<brace-enclosed initializer list>’ to ‘Matrix2<int>’
0赞
Jarod42
7/30/2023
默认情况下,构造函数不会被继承,您必须手动执行:演示您的大部分遗产可能只是 .如果您可以访问 C++20,则不需要任何一个,一个特定的方法就足够了。using
SquaredMatrix
requires (N == M)
0赞
Gerson
7/31/2023
谢谢!我正在使用,所以不可用。这是更新的版本 (3),包含 c 数组和构造函数。C++ 13.1.1 (g++)
requires
initializer_list
0赞
Jarod42
7/31/2023
对于代码,您可以使用 godbold.org(或其他在线编译器)而不是 pastebin.com,因此您有语法、颜色和编译。
评论