c++ - 调用运算符参数评估顺序

标签 c++ language-lawyer

#include <string>

struct X
{
    char y;
    std::string z;

    X & operator()(std::string && s)
    {
        z = std::move(s);
        return *this;
    }

    X & operator()(char c)
    {
        y = c;
        return *this;
    }
};

int main()
{
    X x;
    std::string y("abc");

    x(y[0])(std::move(y));
}
main的最后一行未定义的行为?我猜是的,因为它会扩展为以下内容,但只想确保对调用运算符或成员函数的调用没有更严格的保证
X::operator()(&X::operator()(&x, y[0]), std::move(z))

请添加标准或cppref中的引用

最佳答案

在c++ 17之前,像您的示例一样,修改相同l值的链接函数调用确实是未定义的行为,因为这些表达式的求值顺序未指定。
但是,已修复了proposal并已合并到c++ 17中。
这是相关的rule(重点是我的),其中还包含提案中的示例,展示了其工作原理:

The postfix-expression is sequenced before each expression in the expression-list and any default argument. The initialization of a parameter, including every associated value computation and side effect, is indeterminately sequenced with respect to that of any other parameter. [Note: All side effects of argument evaluations are sequenced before the function is entered (see [intro.execution]). — end note] [Example:

void f() {
 std::string s = "but I have heard it works even if you don't believe in it";
 s.replace(0, 4, "").replace(s.find("even"), 4, "only").replace(s.find(" don't"), 6, "");
 assert(s == "I have heard it works only if you believe in it");       // OK
}

— end example]



尽管上述规则仅严格引用内置的operator(),并且您具有用户定义的运算符,但由于存在rule,因此适用于评估顺序的相同规则:

If either operand has a type that is a class or an enumeration, a user-defined operator function might be declared that implements this operator or a user-defined conversion can be necessary to convert the operand to a type that is appropriate for a built-in operator. ... However, the operands are sequenced in the order prescribed for the built-in operator.

关于c++ - 调用运算符参数评估顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63829690/

相关文章:

c++ - 如何使用 log4cpp 一次记录多个变量?

c++ - 我可以实例化一个 std::reference_wrapper<T> 吗,其中 T 是一个不完整的类型?

c++ - 是否存在将 long 转换为指针有效的情况

c++ - 将map <string,int>保存到文本文件

c++ - 球体体积计算错误,但公式正确

c++ - 在C++标准中,格式正确意味着代码可以编译吗?

c++ - 隐式转换应该在模板参数的上下文中工作吗?

c - 做像 foo(x, &x) 这样的事情安全吗?

c++ - decltype(void()) 中的 void() 究竟是什么意思?

C++ std::string to char 用于 OpenGL LoadBMP