我有一套簡單得多的要求,不需要很多變體的機器。如果我能幫上忙的話,我也不想依靠提振。如何製作boost :: variant的簡化版本?
我需要存儲編譯時已知的任意類型(可能是void
)。它可以是可移植的,也可以是可複製的,如果其中任何一個拋出,則允許所含值不確定。
而不是此值,它也可能包含::std::exception_ptr
或::std::error_code
。
::boost::variant<T, ::std::exception_ptr, ::std::error_code>
將工作,如果T
被允許是無效的。除此之外,::boost::variant
提供了我在這種情況下實際並不需要的'永不保證'。而且,如果我理解它是如何正確工作的,它與可移動但不能複製的類型不兼容。
現在我正在寫很多重複的代碼,我不應該編寫來分別處理這些類型。我還存儲了每種類型的對象的副本,並標記了哪些相關的值。最後,void
給出了整個系統的內容,並要求我在各處寫專業化。
有沒有更好的方法?
這裏是我所擁有的一個簡單例子。這基本上是用來固定結果傳輸到另一個線程,有點像一個有前途的類:
template <typename ResultType>
class stored_result {
public:
stored_result() : is_val_(false), is_err_(false), is_exception_(false) { }
void set_bad_result(::std::error err) {
is_err_ = true;
error_ = ::std::move(err);
}
void set_bad_result(::std::exception_ptr exception) {
is_exception_ = true;
exception_ = ::std::move(exception);
}
void set_result(ResultType res) {
is_val_ = true;
val_ = ::std::move(res);
}
ResultType result() {
if (is_val_) {
is_val_ = false;
return ::std::move(val_);
} else if (is_exception_) {
is_exception_ = false;
::std::rethrow_exception(::std::move(exception_));
} else if (is_error_) {
is_error_ = false;
throw ::std::system_error(error_);
} else {
throw ::std::runtime_error("Asked for result when there was none.");
}
}
private:
bool is_val_, is_err_, is_exception_;
T val_;
::std::exception_ptr exception_;
::std::error_code error_;
};
您可以以透明的方式將'void'映射到唯一的空白類型給用戶。這將允許您重用'boost :: variant',但不需要專業化幫助。 'boost :: variant'的最大亮點是移動結構。 – 2012-04-03 03:10:29
這聽起來很像過早的優化。 – 2012-04-03 03:12:49
@LucDanton:_nod_是的,我在另一個答案中看到了這一點。我想我可以把我的頭圍繞着它如何工作。 – Omnifarious 2012-04-03 03:13:14