以下代码工作正常,但为什么这是正确的代码?为什么foo()返回的临时的"c_str()"指针有效?我想,当输入bar()时,这个临时性已经被破坏了 - 但它似乎不是这样的.那么,现在我假设foo()返回的临时值将在调用bar()之后被销毁 - 这是正确的吗?为什么?
std::string foo() {
std::string out = something...;
return out;
}
void bar( const char* ccp ) {
// do something with the string..
}
bar( foo().c_str() );
Run Code Online (Sandbox Code Playgroud) 可能重复:
C++:临时参数的生命周期?
据说临时变量作为评估完整表达式的最后一步被破坏,例如
bar( foo().c_str() );
Run Code Online (Sandbox Code Playgroud)
临时指针一直存在,直到bar返回,但是为什么
baz( bar( foo().c_str() ) );
Run Code Online (Sandbox Code Playgroud)
是否它仍然存在直到bar返回,或者baz返回意味着完全表达结束在这里,编译器我检查了baz返回后的destruct对象,但我可以依赖它吗?
以前,标准中的一些规则说它们适用于表达式,我很困惑这些规则是否也可以任意应用于全表达式。我得到了那个问题的答案。但是,标准中有一些规则,例如“初始化的完整表达式应为常量表达式。”。如:
dcl.constexpr#9
basic.start.static#2
他们都说full-expression必须是上面这些链接中的常量表达式。
常量表达式的先决条件是它必须是一个核心常量表达式,而且它首先是一个表达式。我们知道expr.const#2中的这些规则应用于expression,而不是应用于不是表达式的 full- expression 。
一个表达式e是一个核心常量表达式除非e的评价,如下所述抽象机的规则,将评估以下中的一个表达式:
但是init-declarator
,哪个是形式declarator initializer(opt)
不是表达式。那么如何解释一个完整的初始化表达式是一个常量表达式呢?或者,在标准方法的句子,这些表述的范围内充分表达都必须是常量表达式?
c++ language-lawyer constant-expression full-expression c++17
如果定义语言构造来生成函数的隐式调用,则出于此定义的目的,语言构造的使用被视为表达式。
然而,这句话的意图尚不清楚。我最好的猜测是,它在这里是为了确保正确的排序并确保在任何隐式函数调用完成之前不会破坏临时变量,但是,我看不到这种情况会适用并改变某些代码的含义。例如:
struct S { };
const S& f() { return {}; }
Run Code Online (Sandbox Code Playgroud)
在这里,return
语句将被视为表达式,操作数{}
也将被视为表达式,因此是return
语句的子表达式。这就是这句话的本意吗?这还能适用于哪些地方并产生有意义的影响?
在这样的代码中
#include <iostream>
#include <memory>
struct A {
int i;
A() {
std::cout << "A()" << std::endl;
}
~A() {
std::cout << "~A()" << std::endl;
}
};
void f(const A& a) {
std::cout << "f(A)" << std::endl;
}
std::unique_ptr<A> make_a() {
return std::make_unique<A>();
}
int main() {
f(*make_a());
}
Run Code Online (Sandbox Code Playgroud)
是否可以保证A
仅在f()
执行对象后删除该对象?