考虑以下内容:

std::string make_what_string( const std::string &id );

struct basic_foo
{
    basic_foo( std::string message, std::string id );
};

struct foo
    : public basic_foo
{
    foo::foo( std::string id)
        : basic_foo( make_what_string( id ), std::move( id ) ) // Is this valid?
    {
    }
};

因为未指定C++中的参数求值顺序,所以我想知道是否
线
basic_foo( make_what_string( id ), std::move( id ) )

上面的代码是有效的。

我知道std::move只是强制转换,但什么时候是std::string
move ctor执行?在评估完所有参数之后,该打电话了
基本构造函数?还是在参数评估期间完成?在
也就是说:

编译器是否这样做:
std::string &&tmp2 = std::move(id);
std::string tmp1 = make_what_string(id);
basic_foo(tmp1, tmp2);

这是有效的。或这个:
std::string tmp2 = std::move(id);
std::string tmp1 = make_what_string(id);
basic_foo(tmp1, tmp2);

这是无效的。请注意,在两种情况下,顺序均为“意外”
一。

最佳答案

请参阅第1.9节:







我认为问题在于不清楚参数的初始化是否被视为与参数表达式相关的副作用。但是,它似乎受到第5.2.2节的支持:



在同一段中也有一条注释使它更清晰:



因此,是的,参数的初始化相对于彼此不确定地排序。初始化可能按照以下任一顺序进行:

std::string message = make_what_string(id);
std::string id = std::move( id );

std::string id = std::move( id );
std::string message = make_what_string(id);

在第二种情况下,make_what_string最终使用了移出的字符串。

因此,即使std::move实际上并没有 move 任何东西,但重要的是,相对于其他参数,实际的 move 也没有顺序。
basic_string(basic_string&& str)的move构造函数的定义如下:



因此,您没有不确定的行为,没有不确定的行为。

关于c++ - move 语义和参数评估顺序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15680489/

10-11 23:06
查看更多