`std::exchange` 为什么不是 `constexpr`?

13

std::exchange是C++14引入的函数,其规定如下:

template< class T, class U = T >
T exchange( T& obj, U&& new_value );

Replaces the value of obj with new_value and returns the old value of obj.

这里是cppreference上的一个可能实现:
template<class T, class U = T>
T exchange(T& obj, U&& new_value)
{
    T old_value = std::move(obj);
    obj = std::forward<U>(new_value);
    return old_value;
}

据我所知,没有什么阻止std::exchange被标记为constexpr。是否有我不知道的原因导致它无法成为constexpr,还是这只是一个疏忽?

5
许多算法都可以成为constexpr,不仅限于这个。你为什么不写一个标准提案,使它们成为constexpr呢?(我是认真的) - Jesper Juhl
6
你能否提供一个使用场景,说明让 std::exchange 成为 constexpr 会带来什么好处? - Sergey Kalinichenko
4
即使它们在编译时已知,例如constexpr,对于obj来说仍然是隐含的const。因此,如果试图在需要常量表达式的上下文中调用该函数,则该函数是不合法的。将其定义为constexpr只是纯粹的愚蠢行为,是一个明显的误导。 - StoryTeller - Unslander Monica
1
@Rakete1111:我的意思是:如果它可以在编译时调用,那么这意味着objconstexpr。如果是这样的话,std::move(obj)还有意义吗?如果objconstexpr,那么它不可移动,对吗? - Nawaz
3
@Nawaz https://godbolt.org/g/79KfnA - Rakete1111
显示剩余10条评论
1个回答

22

2
这在我看来是一个愚蠢的决定,尽管它是无害的。但那就是答案,所以给它 +1。 - StoryTeller - Unslander Monica
7
为什么会说这很傻?没有它,cppreference的例子中将移动构造函数和赋值函数设为constexpr就不能正常工作。参考链接:http://en.cppreference.com/w/cpp/utility/exchange;https://godbolt.org/g/JLSxWr。 - Rakete1111
1
@Rakete1111 - 你会在哪些有意义的场景中使用这个移动构造函数? - StoryTeller - Unslander Monica
3
一个最初被标记为“constexpr”的对象不会被移动(隐式的“const”会妨碍这一点)。正如Nawaz所展示的,在constexpr函数中使用它作为动词是一个有效的观点,这是我没有考虑到的(感谢你提出来)。然而,我仍然认为它的效用并不是太大。 - StoryTeller - Unslander Monica
7
“StoryTeller引用Herb Sutter的会议报告称:‘在这次会议上,Evolution小组还暂时允许constexpr(编译时)new、vector和string’……如果这是未来的趋势,那么如果你想要算法在运行时高效,你将需要在constexpr函数内使用移动语义。” - Massimiliano Janes
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接