c++11 努力理解为什么我不能统一初始化一个结构,但我可以初始化一个类似类型的 std::pair

标签 c++ c++11 uniform-initialization aggregate-initialization

给定以下代码:

#include <functional>
#include <string>
#include <iostream>

class test
{
public:
    struct info
    {
        std::string name {""};
        std::function<bool()> func;
    };

    //info my_info { "test_name", [&]{return member_func();} }; // <------ ERROR HERE

    std::pair<std::string, std::function<bool()>> my_info_pair { "test_name", [&]{return member_func();} };

    bool member_func()
    {
        std::cout << "member_func\n";
        return true;
    };

};

int main() {
    std::cout << "start\n";
    test t;
    std::cout << t.my_info_pair.first << std::endl;
    t.my_info_pair.second();
    std::cout << "end\n";
}

此代码有效。但是,如果我取消对注释掉的行的注释——它试图以与 std::pair 初始化相同的方式初始化一个 info 结构,那么它将失败。我不明白为什么...

得到的错误是:

prog.cc:15:60: error: could not convert '{"test_name", <lambda closure
object>test::<lambda()>{((test*)this)}}' from '<brace-enclosed
initializer list>' to 'test::info'
     info my_info { "test_name", [&]{return member_func();} };
                                                             ^

链接到我的测试代码:here (wandbox)

最佳答案

这里的问题是

std::string name {""};

您使用类成员初始值设定项,并且在 C++11 中,如果您希望对象成为聚合(根据 [dcl.init.aggr]/1),则不允许这样做。要使其在 C++11 中编译,您必须将其删除。

在 C++14 及更高版本中,该约束已被删除(已更新 [dcl.init.aggr]/1),并且在聚合中允许使用类成员初始值设定项,代码将按原样编译。

关于c++11 努力理解为什么我不能统一初始化一个结构,但我可以初始化一个类似类型的 std::pair,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55380720/

相关文章:

c++ - 为什么我不能转发声明内部友元类?

c++ - 高效施工代表团

c++ - 如何使用 C++11 统一初始化语法?

c++ - 基本类型的统一初始化?

c++ - 用 std::uniform_real_distribution<double> 初始化一个 N 大小的 std::vector

c++ - C++中的协同过滤库

c++ - for std::queue remove all of element swap 和 pop 的时间差

c++ - 检查子成员是否为NULL

c++ - std::function 的模板参数是如何工作的? (执行)

c++ - 字符串的 std::end 是否应该指向空终止符?