【发布时间】:2022-06-14 01:16:26
【问题描述】:
我正在探索在没有边车大小信息的情况下存储文字数组(任何类型)的方法。我已经勾勒出了一些方法,但对于每一种方法都有一些挥之不去的问题。这里我使用std::initializer_list,而不是模板化std::array。请注意,这是一个简单的测试用例,实际的类可能有额外的成员、额外的模板参数和必须提供的模板参数。
struct B {
std::initializer_list<const char*> a;
int b;
};
// Helper for the question
constexpr std::initializer_list<const char*> get1() {
// Confirm: string literals, lifespan OK?
return {"1", "2", "3"};
}
既然我正在处理文字值(存储在代码中),为什么不使用初始化列表对象而不是模板化 std::array?虽然列表不会拥有其内容的所有权,但作为文字值,它们永远不会超出范围。此外,不需要指定列表大小 - 无论大小如何,都不需要模板。唯一的问题是缺少下标运算符,导致代码略显冗长。使用初始化列表的绝妙想法来自 IRC。看看我能做的所有巧妙的事情:
auto b = B{{"1","2","3"}};
auto b = B{get1()};
std::cout << b.a.begin()[2] << ", size: " << b.a.size() << std::endl;
for (auto& e: b.a) { std::cout << e << std::endl; }
auto l = [](const char* s) { return !strcmp(s, "2"); };
auto r = std::find_if(begin(b.a), end(b.a), l);
std::cout << "result: " << *r << std::endl;
初始化列表的底层存储是字符串文字吗?由于字符串文字是全局的,初始化列表在程序期间是否有效?请参阅以下示例。我有悬空指针的风险吗?如果没有,我如何使警告静音?
auto b = B{{"1","2","3"}};
auto b = B{get1()};
【问题讨论】:
-
"我正在探索在没有 sidecar 大小信息的情况下存储文字数组(任何类型)的方法。" 你为什么要这样做?未调整大小的数组不是一件好事。
-
信息还在,只是编译器提供的,而不是用户提供的。
-
所以这个真正是你想从一个包含括号初始化列表的表达式创建一个
auto-deduced变量,没有明确指定该表达式该列表的大小是多少。也就是说,你想要auto lit_list = something{"lit1", "lit2", "lit3"},其中something没有指定3。
标签: c++ c++20 lifetime literals