英文:
Is taking a reference from a temporary valid C++ code?
问题
以下是您要翻译的代码部分:
for (auto& numberString: {"one", "two", "three", "four"}) { /* ... */}
这段代码是否有效?据我所知,根据这个问题,这应该是不合法的,但代码可以正常运行。我认为我对此问题的理解可能是不正确的。
据我所知,只有字面值不应该有内存地址,但链接的问题是在讨论临时值和r-values。
英文:
I used the following syntactic sugar:
for (auto& numberString: {"one", "two", "three", "four"}) { /* ... */}
Is this valid code? AFAIK, based on this question, this should be illegal, yet the code runs as expected. I don't think my understanding is correct on the matter.
As far as I know, only literals should not have memory addresses, yet the linked question is talking about temporaries and r-values.
答案1
得分: 28
Yes, this code is valid.
Keep in mind that (for C++17), the compiler will semantically replace the range-based for loop by the construct
{
auto && __range = {"one", "two", "three", "four"};
for (auto __begin = begin(__range), __end = end(__range); __begin != __end; ++__begin)
{
auto& numberString = *__begin;
/* ... */
}
}
You see, the lifetime of the initializer_list
is extended to the lifetime of __range
inside of the outermost scope in the replacement.
Note, however, that you still can easily cause undefined behavior if the range expression contains a temporary itself:
struct some {
auto get_list() { return {"one", "two", "three", "four"}; }
};
some foo() { return some{ }; }
for(auto& numberString : foo().get_list()) { /* ... */ }
The above code will result in a dangling reference in <= C++20.
Only in C++23, the lifetime of the temporary created by foo()
will get extended such that it becomes valid. See also https://en.cppreference.com/w/cpp/language/range-for
英文:
Yes, this code is valid.
Keep in mind that (for C++17), the compiler will semantically replace the range-based for loop by the construct
{
auto && __range = {"one", "two", "three", "four"};
for (auto __begin = begin(__range), __end = end(__range); __begin != __end; ++__begin)
{
auto& numberString = *__begin;
/* ... */
}
}
You see, the lifetime of the initializer_list
is extended to the lifetime of __range
inside of the outermost scope in the replacement.
Note however that you still can easily cause undefined behavior if the range expression contains a temporary itself:
struct some {
auto get_list() { return {"one", "two", "three", "four"}; }
};
some foo() { return some{ }; }
for(auto& numberString : foo().get_list()) { /* ... */ }
The above code will result in a dangling reference in <= C++20.
Only in C++23, the lifetime of the temporary created by foo()
will get extended such that it becomes valid. See also https://en.cppreference.com/w/cpp/language/range-for
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论