C++中std::is_nothrow_assignable类函数参数传递规则问询
C++类型特性中const与引用限定符的使用逻辑
这些带nothrow的类型特性,核心作用是精确匹配你要验证的代码操作的类型签名,参数里的const、&/&&不是随便加的,完全对应实际代码里的操作场景。
1. 以is_nothrow_assignable为例
is_nothrow_assignable<LHS, RHS>的本质是检查表达式:
static_cast<LHS>(lhs) = static_cast<RHS>(rhs);
是否合法且不会抛出异常。
两种写法的差异
- 你自己测试用的
is_nothrow_assignable<B,A>:
对应的是值类型赋值,即B{} = A{}——用临时A对象给临时B对象赋值,这是在检查类是否支持值到值的赋值操作。 std::exchange里的is_nothrow_assignable<_Ty&, _Other>:
对应的是实际代码里的_Val = static_cast<_Other&&>(_New_val),其中_Val是_Ty&类型的左值引用,static_cast<_Other&&>(_New_val)最终的类型是_Other(右值引用折叠规则)。这里必须把第一个参数写成_Ty&,因为实际操作的是左值对象的赋值,如果直接传_Ty,相当于检查临时对象的赋值(多数场景无意义,甚至很多类会禁用)。
2. 以is_nothrow_constructible为例
is_nothrow_constructible<T, Args...>是检查用Args类型的参数构造T对象的操作:
T(args...);
是否合法且无异常。
std::pair构造函数的例子
std::pair的构造函数参数是const T1& x,构造T1成员时执行的是T1(x),其中x的类型是const T1&。所以必须用is_nothrow_constructible<T1, const T1&>来匹配这个构造操作——如果写成is_nothrow_constructible<T1, T1>,检查的是值传递的拷贝构造,和实际的const T1&引用传递构造完全是两个场景。
如何判断何时使用限定符?
核心原则:让类型特性的模板参数完全对应你要验证的代码表达式的类型签名:
- 对于赋值操作:
- 确定左值的实际类型(是普通引用?const引用?),作为
is_nothrow_assignable的第一个参数; - 确定右值的实际类型(包括是否是右值、const等),作为第二个参数。
- 确定左值的实际类型(是普通引用?const引用?),作为
- 对于构造操作:
- 第一个参数是要构造的目标类型;
- 后续参数完全对应构造时传入的参数的实际类型(包括
const、&/&&)。
内容的提问来源于stack exchange,提问作者user11611653
相关产品推荐
相关产品推荐

