初始化std::optional结构体成员

编程语言 2026-07-10

这段语法被注释掉了,是我在这种情况下想要使用的。使用 .headers = {{"Set-Cookie", "12345678"}} 只有在 headers 成员不是 std::optional<X> 类型、而仅仅是unordered_map时才起作用。在这里我需要在把它们传入初始化器之前对可选值进行初始化,否则代码将无法编译。

#include <iostream>
#include <optional>
#include <unordered_map>

struct HttpResponse {
    int status;
    std::optional<std::unordered_map<std::string, std::string>> headers;
};

HttpResponse myFunc(bool success) {
    if (success) {
        std::unordered_map<std::string, std::string> headers_to_return = {{"Set-Cookie", "12345678"}};
        return HttpResponse{
            .status = 200,
            .headers = headers_to_return
            // Nicer syntax
            // .headers = {{"Set-Cookie", "12345678"}}
        };
    }
    else {
        return HttpResponse{
            .status = 403
        };
    }
}       

int main() {
    HttpResponse res = myFunc(true);
    if (res.headers) {
        for (auto& header_pair : res.headers.value())
            std::cout << header_pair.first << ": " << header_pair.second << std::endl;
    }
    return 0;
}

如果存在解法,可以使用一个比C++20更新的标准

https://godbolt.org/z/W5Wf99Yo8

解决方案

你需要再多一对花括号:

return HttpResponse{
    .status = 200,
    .headers = {{{"Set-Cookie", "12345678"}}}
};

最外层的大括号是用于初始化传给 optional 构造函数的 unordered_map 的初始化器(会被隐式转换),中间的大括号是用于初始化传给 unordered_map 构造函数的 initializer_list 的初始化器,最内层的大括号是用于初始化 std::pair 的初始化器,因此你将得到:

HttpResponse{
    .status = 200,
    .headers =
        std::unordered_map<std::string, std::string>{
            std::initializer_list<std::pair<const std::string, std::string>>{
                std::pair<const std::string, std::string>{
                    "Set-Cookie", "12345678"
                }
            }
        }
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章