Sae*_*ani 0 c++ templates c++20
我在下面的代码中提出了一个意想不到的行为(据我自己有限的知识),它不尊重默认成员初始化值。我有一个单参数赋值的承包商,它应该从赋值运算符构建类。我忘记使用正确的参数名称,最终遇到了这个问题(请参阅带有故意错误的单参数构造函数的行:
为什么我得到垃圾值而不是成员初始化值?
我自己的假设是因为模板类,0与0.0不同......但尝试过并遇到了同样的问题。
#include <iostream>
#include <concepts>
template <class T>
requires std::is_arithmetic_v<T>
class Complex
{
private:
T re = 0;
T im = 0;
public:
Complex() {
std::cout << "Complex: Default constructor" << std::endl;
};
Complex(T real) : re{re} { // should be re{real}, but why re{re} is not 0?
std::cout << "Complex: Constructing from assignement!" << std::endl;
};
void setReal(T t) {
re = t;
}
void setImag(const T& t) {
im = t;
}
T real() const {
return re;
}
T imag() const {
return im;
}
Complex<T>& operator+=(const Complex<T> other) {
re+= other.re;
im+= other.im;
return *this;
}
bool operator<(const Complex<T>& other) {
return (re < other.re && im < other.im);
}
};
int main() {
Complex<double> cA;
std::cout<< "cA=" << cA.real() << ", " << cA.imag() << "\n";
Complex<double> cB = 1.0; // Should print "1.0, 0" but prints garbage
std::cout<< "cB=" << cB.real() << ", " << cB.imag() << "\n";
Complex<int> cC = 1;
std::cout<< "cC=" << cC.real() << ", " << cC.imag() << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出示例:
复杂:默认构造函数 cA=0, 0 复杂:从赋值构造!cB=6.91942e-310, 0 复杂:根据赋值构造!cC=4199661, 0
CompilerExplorer上的代码。
Complex(T real) : re{re} { // should be re{real}, but why re{re} is not 0?
Run Code Online (Sandbox Code Playgroud)
如果您在构造函数中显式为成员提供初始值设定项,则此初始值设定项将替换默认成员初始值设定项。在这种情况下根本不使用默认成员初始值设定项。
需要明确的是:默认成员初始值设定项不会在构造函数调用之前初始化成员。它们只是“填充”构造函数的成员初始值设定项列表中未提及的成员的初始值设定项。
在您的情况下re{re},访问一个超出其生命周期(re)的对象,导致未定义的行为。
另外,作为旁注:Complex<double> cB = 1.0;和Complex<int> cC = 1;不是赋值。两者都是带有初始化的声明。不是=赋值表达式的一部分,并且不会operator=像赋值那样调用。它们都是复制初始化,与之相反的Complex<double> cB(1.0);是直接初始化。
这些初始化所使用的构造函数Complex(T real)称为转换构造函数。