GCC 中忽略默认成员值初始化

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上的代码。

use*_*522 5

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)称为转换构造函数