是什麼,在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」是否關心它,性狀都應該正確。 –