是什么,在C++标准而言,预期的(如果有的话)下面的程序的输出:对于具有抛出拷贝构造函数和noexcept按值拷贝赋值的类,is_nothrow_copy_assignable的值是多少?
#include <iostream>
#include <iomanip>
#include <type_traits>
class A {
public:
A() = default;
~A() = default;
A(A const& other) {}
A(A&& other) noexcept {}
A& operator=(A other) noexcept { return *this; }
};
int main() {
std::cout << std::boolalpha
<< std::is_nothrow_copy_assignable<A>::value << "\n"
<< std::is_nothrow_move_assignable<A>::value << "\n";
}
换句话说,不将型性状值的分析看的声明只有赋值运算符,这是noexcept,并且它从而得到
true
true
抑或是考虑调用上下文(a
,b
是A
实例)
a = b; // may throw, implicitly calls copy c'tor
a = std::move(b); // noexcept, implicitly calls move c'tor
和它产生
false
true
实践尝试
运行与Visual Studio 2015的代码,更新3给出
true
true
而GCC 6.1提供了
false
true
谁对?
背景
,当我们有一个投掷的拷贝构造函数的资源管理类(因为资源分配可能会失败),这样的情况发生时,noexcept移动构造函数,一个投掷拷贝赋值和noexcept移动分配。
假设都复制和移动分配可以在交换IDOM方面能够高效地实现:
A& operator=(A const& other) {
A(other).swap(*this); // calls the copy c'tor, may throw
return *this;
}
A& operator=(A&& other) noexcept {
A(std::move(other)).swap(*this); // calls noexcept move c'tor
return *this;
}
然后,我们可能会考虑冷凝双双进入单按值拷贝赋值
A& operator=(A other) noexcept {
other.swap(*this);
return *this;
}
但是,如果std::is_nothrow_copy_assignable<A>
和std::is_nothrow_move_assignable<A>
提供了正确的值(分别为false和true),我们只能安全地执行此操作。否则,依赖于这些类型特征的代码将表现得很差,我们的单个按值分配而不是是两个单独赋值运算符的正确替代。
对于'vector',你需要'is_nothrow_move_assignable'是正确的,但不一定是'is_nothrow_copy_assignable'。也没有必要使用'boolalpha'两次。 –
感谢您的评论。我已经编辑了相应的问题。当然,即使'std :: vector'不需要它,''nothrow_copy_assignable'仍然应该正确运行。 – jbab
其实我很困惑。 'vector'要求'is_nothrow_move_constructible'是正确的,以在重新分配期间获得完全的效率。我不记得它是否真的需要'is_nothrow_move_assignable'。但是,是的,无论“vector”是否关心它,性状都应该正确。 –