使用 C++23 将会有
std::pair<T1, T1>::operator =( const pair &other ) const;
Run Code Online (Sandbox Code Playgroud)
对我来说,对 const 对象进行赋值运算符没有任何意义,因为对象无法修改。为什么 C++23 在pair上有这个运算符?更令人困惑的是:
std::pair<T1, T1>::operator =( pair &&other ) const;
Run Code Online (Sandbox Code Playgroud)
[编辑]:这不起作用,因为 this 指向的内容将是 const:
template<typename T>
struct S
{
void operator +=( T x ) const;
T m_x;
};
template<typename T>
void S<T>::operator +=( T x ) const
{
m_x += x;
}
int main( int argc, char **argv )
{
S<int> si;
si += 1;
}
Run Code Online (Sandbox Code Playgroud)
那么为什么会有一个带有pair的const限定赋值运算符呢?
Hol*_*Cat 11
这对于成对的非常量引用是有意义的。即使在 时,这些仍然是可分配的const。考虑:
#include <iostream>
template <typename T>
void foo(const T x) {x = 42;}
int main()
{
int y = 1;
foo<int &>(y);
std::cout << y << '\n'; // 42
}
Run Code Online (Sandbox Code Playgroud)
但为什么还要费力支持它呢std::pair?
我最近在某处看到了一个解释,但找不到链接(找到了)。它的大致思路是:
您正在创建一个通用算法,并将结果分配给模板中的函数结果(例如分配给取消引用的迭代器)。如果函数碰巧按值返回,您可能会默默地得到意外行为(赋值不执行任何操作)。
您希望出现编译错误,但实际上没有人
&限定其赋值运算符。
那么合乎逻辑的下一步是检查返回类型并拒绝非引用。
但你想留下一个漏洞。例如,取消引用std::vector<bool>迭代器按值返回(代理对象),并且应该允许对其进行赋值。
你可以为它发明一种类型特征,但还有一个聪明的选择。const如果添加到返回类型,则检查赋值是否仍然可以编译。如果没有,则会引发编译错误。这很好地概括为返回引用,因为添加const到它们会使类型保持不变(如果引用是非常量,则仍然可以分配)。
为了使其工作,您需要添加const所有此类类型的赋值运算符(这是为 完成的std::vector<bool>::reference)。
至于为什么std::pair(和std::tuple)需要它:从std::views::zip()取消引用到引用元组的迭代器,并且您希望能够分配给这些元组。
但我不记得 C++23 中哪些标准算法会受到这样的约束。可能是某个范围内的东西...