矩阵构造函数的括号括起来的初始值设定项在类型 std::complex<double> 中失败 >
Brace-enclosed initializer for matrix constructor fail in type std::complex<double> >
我为我的矩阵 class 实现了一个构造函数,以使用嵌套 std::initializer_list 进行大括号括起来的初始化。构造函数适用于主要类型:`int`、`double`;但会呈现“复杂”的错误阅读。如何解决这个错误阅读?
矩阵class
template <typename T> class xxx
{
public:
T *ptr;
int col, row, size;
xxx() = delete;
xxx(const int i, const int j):row(i), col(j), size(i*j)
{
ptr = new T [this->size] ;
}
xxx(const std::initializer_list< std::initializer_list<T> > s):xxx(s.size(), s.begin()->size())
{
int j = 0;
for (const auto& i : s) { std::copy (i.begin(), i.end(), ptr + j*col); ++j ; }
}
~xxx() {delete [] this->ptr;}
T operator()(const int i, const int j) const { return ptr[i*col+j]; }
};
这里添加一个典型的输出重载以完成。
template <typename X> std::ostream& operator<<(std::ostream&p, const xxx<X>&a)
{
for (int i=0; i<a.row; i++) {
for (int j=0; j <a.col; j++) p << std::setw(6) << a(i, j);
p << std::endl;
}
return p;
}
`double` 类型的第一个测试 main() 运行良好。
#include <iostream>
#include <initializer_list>
#include <iomanip>
#include <complex>
int main()
{
xxx<double> x = {{1, 2,3,4} , {3, 4,5,6}, {5, 6,7,8} };
std::cout << x << std::endl;
}
它打印出预期的内容:
$ ./a.exe
1 2 3 4
3 4 5 6
5 6 7 8
然后,我尝试使用我感兴趣的另一种类型,`complex`:
int main()
{
xxx< std::complex<double> > z = { {(1,2), (3,4)}, {(5,6), (7,8)} };
std::cout << z << std::endl;
}
输出错误如下:
$ ./a.exe
(2,0) (4,0)
(6,0) (8,0)
想象部分缺失,真实部分取反想象部分的值。任何想法或建议将不胜感激。
您的问题与初始化列表无关。问题是这段代码
#include <iostream>
#include <complex>
int main()
{
std::complex<double> x = (1,2);
std::cout << x;
}
没有按照您的预期去做。输出是
(2,0)
因为 (1,2)
是 comma operator 在工作。 std::complex<double> x = (1,2);
等同于 std::complex<double> x = 2;
.
需要使用大括号进行初始化:
#include <iostream>
#include <complex>
int main()
{
std::complex<double> x = {1,2};
std::cout << x;
}
输出
(1,2)
PS 我强烈建议您使用 std::vector<T>
而不是 T*
来保存数据。由于不遵循 3/5 规则,目前复制 xxx
将导致未定义的行为。
我为我的矩阵 class 实现了一个构造函数,以使用嵌套 std::initializer_list 进行大括号括起来的初始化。构造函数适用于主要类型:`int`、`double`;但会呈现“复杂”的错误阅读。如何解决这个错误阅读?
矩阵class
template <typename T> class xxx
{
public:
T *ptr;
int col, row, size;
xxx() = delete;
xxx(const int i, const int j):row(i), col(j), size(i*j)
{
ptr = new T [this->size] ;
}
xxx(const std::initializer_list< std::initializer_list<T> > s):xxx(s.size(), s.begin()->size())
{
int j = 0;
for (const auto& i : s) { std::copy (i.begin(), i.end(), ptr + j*col); ++j ; }
}
~xxx() {delete [] this->ptr;}
T operator()(const int i, const int j) const { return ptr[i*col+j]; }
};
这里添加一个典型的输出重载以完成。
template <typename X> std::ostream& operator<<(std::ostream&p, const xxx<X>&a)
{
for (int i=0; i<a.row; i++) {
for (int j=0; j <a.col; j++) p << std::setw(6) << a(i, j);
p << std::endl;
}
return p;
}
`double` 类型的第一个测试 main() 运行良好。
#include <iostream>
#include <initializer_list>
#include <iomanip>
#include <complex>
int main()
{
xxx<double> x = {{1, 2,3,4} , {3, 4,5,6}, {5, 6,7,8} };
std::cout << x << std::endl;
}
它打印出预期的内容:
$ ./a.exe
1 2 3 4
3 4 5 6
5 6 7 8
然后,我尝试使用我感兴趣的另一种类型,`complex`:
int main()
{
xxx< std::complex<double> > z = { {(1,2), (3,4)}, {(5,6), (7,8)} };
std::cout << z << std::endl;
}
输出错误如下:
$ ./a.exe
(2,0) (4,0)
(6,0) (8,0)
想象部分缺失,真实部分取反想象部分的值。任何想法或建议将不胜感激。
您的问题与初始化列表无关。问题是这段代码
#include <iostream>
#include <complex>
int main()
{
std::complex<double> x = (1,2);
std::cout << x;
}
没有按照您的预期去做。输出是
(2,0)
因为 (1,2)
是 comma operator 在工作。 std::complex<double> x = (1,2);
等同于 std::complex<double> x = 2;
.
需要使用大括号进行初始化:
#include <iostream>
#include <complex>
int main()
{
std::complex<double> x = {1,2};
std::cout << x;
}
输出
(1,2)
PS 我强烈建议您使用 std::vector<T>
而不是 T*
来保存数据。由于不遵循 3/5 规则,目前复制 xxx
将导致未定义的行为。