我了解到,对已经进行后置递增的变量进行再次使用是函数调用中的未定义行为。我的理解是这在构造函数中不是问题。我的问题是关于
假设:
tie
,它奇怪地处于两者之间。假设:
pair<int, int> func()
,我能做到:tie(*it++, *it) = func();
或者那是未定义的行为?
tie
,它奇怪地处于两者之间。pair<int, int> func()
,我能做到:tie(*it++, *it) = func();
或者那是未定义的行为?
根据 N4140 [intro.execution]/15:
在调用函数时(无论该函数是否为内联函数),与任何参数表达式或指定被调用函数的后缀表达式相关的每个值计算和副作用都会在调用函数体中的每个表达式或语句执行之前进行排序。[注意:与不同参数表达式相关的值计算和副作用是无序的。--结束语] 在调用函数体的执行之前,调用函数中的每个评估(包括其他函数调用)如果没有特别排序,则与调用函数的执行无序排序。C++中的几个上下文会导致函数调用的评估,即使翻译单元中没有相应的函数调用语法也是如此。[例如:新表达式的评估会调用一个或多个分配和构造函数;参见[expr.new]。对于另一个例子,在没有函数调用语法出现的情况下,可以在转换函数([class.conv.fct])的调用中出现。-结束示例] 上述调用函数的执行排序约束条件是函数调用作为评估的特征,无论调用函数的表达式语法如何。换句话说,函数执行不会互相交错。foo(f(x),g(x));
也是完全可以的。 - M.Moperator++
作为函数可以防止操作重叠/交错一样,一元运算符 operator*
成为一个函数也是足够的(那么 operator++
就不需要了),这难道不是可以的吗?(注意,根据 as-if 规则,编译器实际上允许交错多个函数调用,只要按照顺序一致性规则的结果与某些允许的非重叠顺序相同即可)。 - Ben Voigtoperator*
?因为第一个参数中的 operator*
明显在 operator++
的值计算之后被排序。但如果这是未定义的,那么只有 operator++
是函数的情况也是如此,因为它可能会在另一个操作数的解引用过程中被调用。解引用被增量中断似乎和不完整的增量一样有害。所以我想你需要两个都是函数。 - Ben Voigt
std::tie
是 一个函数。我不认为它会有什么不同。 - super