c++ - 如何使用初始化列表构造函数以外的东西为类成员设置默认值

标签 c++ default-value member-initialization

假设我有这样的东西:

class A
{
public:
    A(int x, int y)
    {
        std::cout << "Constructed from parameters" << std::endl;
    }

    // Non-copyable, non-movable
    A(A const&) = delete;
    A(A&&) = delete;
    A& operator=(A const&) = delete;
    A& operator=(A&&) = delete;
};
    
class B
{
public:
    B() = default;

private:
    A a{1,2};
};
    
int main()
{
    B b;
    return 0;
}

这工作正常,通过调用 A 的构造函数用默认值初始化 a,并打印 Constructed from parameters


然后,假设我想以不同的方式初始化 a,因此我添加了一个采用初始化列表的构造函数并更改了我的代码:

class A
{
public:
    A(int x, int y)
    {
        std::cout << "Constructed from parameters" << std::endl;
    }
        
    A(std::initializer_list<int> someList)
    {
        std::cout << "Constructed from an initializer list" << std::endl;
    }

    // Non-copyable, non-movable
    A(A const&) = delete;
    A(A&&) = delete;
    A& operator=(A const&) = delete;
    A& operator=(A&&) = delete;
};
    
class B
{
public:
    B() = default;

private:
    A a{1,2,3};
};
    
int main()
{
    B b;
    return 0;
}

一切仍然如我所愿,代码通过调用 A 的第二个构造函数用默认值初始化 a 并打印 Constructed from an initializer list.


现在,假设我想保持 A 不变,但返回到通过第一个构造函数设置 a 的默认值。如果 A 是可移动的,我可以使用 A a = A(1,2);,但这里不是这种情况,那么我该怎么做呢?使用该构造函数设置默认值显然是不可能的吗?

编辑:我正在寻找适用于 C++14 的解决方案,但如果在 C++17 或 C++20 中有更好的解决方案,那也是我想知道的。

最佳答案

If A was movable, I could use A a = A(1,2);, but that isn't the case here

好吧,对于 C++17 及更高版本,您可以在这里使用 A a = A(1,2);,只要您将它作为声明/初始化!以下作品(在您的第二个代码片段中):

class B {
public:
    B() = default;
private:
    A a = A( 1, 2 ); // No assignment here - just an initialization.
};

和“从参数构造”被调用。这是因为这里没有实际的赋值操作,只是一个初始化。但是,由于您所说的原因,以下操作将失败:

class B {
public:
    B() { a = A( 1, 2 ); } // error C2280: 'A &A::operator =(A &&)': attempting to reference a deleted function
private:
    A a{ 1,2,3 };
};

编辑:C++17 之前的版本,以下是一种解决方法,在 B 的默认构造函数的初始化列表中使用“老式”圆括号,而不是大括号(在 clang-cl 和 MSVC 中使用 C++14 测试):

class B {
public:
    B() : a(1,2) {} // Using a{1,2} calls the "initializer list" constructor, however!
private:
    A a;
};

关于c++ - 如何使用初始化列表构造函数以外的东西为类成员设置默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64481212/

相关文章:

javascript - 从选择字段Javascript获取默认值

php - MySQL 默认 date() + 14 天,对于一个列?

c++ - 使用 C++11 的成员初始化列表中的初始化列表语法

c++ - OS X 从 Carbon 到 Cocoa 窗口创建?

c++ - 如何计算 NumericVectors?

c++ - 给定抽象基类 X,如何创建另一个模板类 D<T>,其中 T 是从 X 派生的类的类型?

c++ - 如何在静态库中提供默认的 YAML 配置值?

c++ - 努力理解 'member initializing'

c++ - 修改成员初始值设定项列表

c++ - 为什么 snprintf 在打印单个数字时始终比 ostringstream 快 2 倍?