抱歉尴尬的标题,但我找不到更好的标题.
考虑这个示例代码(除了说明问题之外没有任何目的):
#include <vector>
void FooBar(int);
void func1()
{
static std::vector<int> vec {1, 2, 3, 4};
for (auto & v : vec)
FooBar(v);
}
void func2()
{
for (auto & v : std::vector<int> {1, 2, 3, 4})
FooBar(v);
}
Run Code Online (Sandbox Code Playgroud)
可以在此处找到对此的反汇编
在func1静态vec向量中应该在启动时一劳永逸地构造.实际上上面提到的godbolt上的反汇编表明静态的初始化vec只在第一次调用时完成,func1而不是在启动时完成,但这不是重点.
现在考虑func2:这里向量直接在for语句中声明为"内联"(不确定这是如何实际调用的),但当然每次func2调用时都会构造该向量.
是否有静态声明向量的方式与里面for的语句,像for (auto & v : static std::vector<int> { 1, 2, 3, 4})这是不幸的是没有合法的C++.
Sto*_*ica 12
这实际上对你没有帮助.但是你可以在C++ 2a中做些什么.但是,它基于C++ 14和C++ 17中已有的东西.
C++ 2a添加了一个init-statement基于循环的范围.这是新的一点,旧的一点是,它与init-statement今天定义的相同.定义如下([stmt.stmt]):
init-statement:
expression-statement
simple-declaration
Run Code Online (Sandbox Code Playgroud)
我想要的是a simple-declaration可能包含一个static限定符.是的,它会做你所期望的.所以在C++ 2a中你可以写:
for (static std::vector<int> vec {1, 2, 3, 4}; int v : vec) {
// Do things.
}
Run Code Online (Sandbox Code Playgroud)
如果你想今天测试它的编译器支持,这里是一个C++ 17 kludge:
if (static std::vector<int> vec {1, 2, 3, 4}; true) {
// init-statement in if was added in C++17
for(int v : vec)
FooBar(v);
}
Run Code Online (Sandbox Code Playgroud)
它的拆卸.
使用lambda的另一个选项(来自主要问题的评论):
void func()
{
for(auto & v : ([]() -> std::vector<int>& { static std::vector<int> vec{1, 2, 3, 4}; return vec; })())
FooBar(v);
}
Run Code Online (Sandbox Code Playgroud)