在 C++ 中将参数传递给 std::is_nothrow_assignable 类函数的正确形式是什么?

问题描述 投票:0回答:1

我正在研究

noexcept
说明符和
noexcept
运算符的功能。 我知道除了使用
noexcept
运算符之外,还有一些类型特征可以替代使用,例如:

- is_nothrow_constructible
- is_nothrow_default_constructible
- is_nothrow_move_constructible
- is_nothrow_copy_constructible
- is_nothrow_assignable
- is_nothrow_move_assignable
- is_nothrow_copy_assignable
- is_nothrow_destructible

例如,在

is_nothrow_assignable
is_nothrow_constructible
的情况下。

struct A { };
struct B {
  B& operator= (const A&) noexcept {return *this;}
  B& operator= (const B&) {return *this;}
};

int main() {
  std::cout << std::boolalpha;
  std::cout << "is_nothrow_assignable:" << std::endl;
  std::cout << "A=A: " << std::is_nothrow_assignable<A,A>::value << std::endl;
  std::cout << "B=A: " << std::is_nothrow_assignable<B,A>::value << std::endl;
  std::cout << "B=B: " << std::is_nothrow_assignable<B,B>::value << std::endl;
  return 0;
}

在上面的代码中,很明显它测试一种类型是否可以像

std::is_nothrow_assignable<B, A>
那样不可抛出分配。

但是,我在 C++ 标准库的一些模板中看到它们使用

const
和/或
&/&&
传递参数,而其他一些模板则不使用它,类似于
std::exchange
的定义:

_EXPORT_STD template <class _Ty, class _Other = _Ty>
_CONSTEXPR20 _Ty exchange(_Ty& _Val, _Other&& _New_val) noexcept(
    conjunction_v<is_nothrow_move_constructible<_Ty>, is_nothrow_assignable<_Ty&, _Other>>) { // HERE
    // assign _New_val to _Val, return previous _Val
    _Ty _Old_val = static_cast<_Ty&&>(_Val);
    _Val         = static_cast<_Other&&>(_New_val);
    return _Old_val;
}

std::exchange
的参数类型为:
_Ty&, _Other&&

在函数的第三行中使用

is_nothrow_assignable
为:

    is_nothrow_assignable<_Ty&, _Other>
    //                       ^        ^
    //                       |        |
    // Here is passing as reference   |
    //                               But not here

在其他函数中也有类似的东西:

//const& ----------------
//          |           |
pair(const T1& x, const T2& y) noexcept(  
        is_nothrow_constructible<T1, const T1&>::value &&
        is_nothrow_constructible<T2, const T2&>::value );
//                               ^     ^     ^
//                               |     |     |
// Here without const or & ------      |     |
//                                     |     |
// But here is with const and & -------------

我的问题是为什么他们在某些论点中使用

const
和/或
&/&&
而在其他论点中则不使用? 我如何确定何时/何地使用它们?

c++ templates type-traits noexcept
1个回答
0
投票

is_nothrow_assignable<T, U>
告诉你,鉴于

T&& f();
U&& g();

f() = g()
是否有效且不抛出。

由于参考折叠,当

T
是参考时,
T&&
T
相同。否则,如您所料,
T&&
是“对
T
的右值引用”。

因此,对于某些对象类型

A
B

  • is_nothrow_assignable<A, B>
    告诉您是否可以从 A 类型的
    rvalue
    分配 B 类型的
    rvalue
    ,而不会引发异常。这一点也不有趣,因为你很少需要分配给右值。
  • is_nothrow_assignable<A&&, B&&>
    相当于
    is_nothrow_assignable<A, B>
  • is_nothrow_assignable<A&, const B&>
    告诉您是否可以从 A 类型的
    const lvalue
    分配 B 类型的
    lvalue
    ,而不会引发异常。
  • is_nothrow_assignable<A&, B>
    告诉您是否可以从 A 类型的
    rvalue
    分配 B 类型的
    lvalue
    ,而不会引发异常。
  • is_nothrow_assignable<A&, B&&>
    相当于
    is_nothrow_assignable<A&, B>
© www.soinside.com 2019 - 2024. All rights reserved.