相關(guān)的類
- Status
StatusWith<ResultType>
用于返回結(jié)果,如果計(jì)算結(jié)果的過(guò)程中出現(xiàn)錯(cuò)誤优训,則返回錯(cuò)誤狀態(tài) Status
敌卓。源碼中有一個(gè)例子,可以形象的看出 StatusWith
的使用方法终佛。
StatusWith<int> fib( int n ) {
if ( n < 0 )
return StatusWith<int>( ErrorCodes::BadValue, "parameter to fib has to be >= 0" );
if ( n <= 1 ) return StatusWith<int>( 1 );
StatusWith<int> a = fib( n - 1 );
StatusWith<int> b = fib( n - 2 );
if ( !a.isOK() ) return a;
if ( !b.isOK() ) return b;
return StatusWith<int>( a.getValue() + b.getValue() );
}
StatusWith
包含一些實(shí)現(xiàn)的細(xì)節(jié),如:
- 禁用
StatusWith<Status>
和StatusWith<StatusWith<T>>
TagType
transform
下文主要針對(duì)這些細(xì)節(jié)雾家,做了一定的解讀查蓉。
禁用 StatusWith<Status> 和 StatusWith<StatusWith<T>>
代碼中使用如下語(yǔ)句在編譯期間檢測(cè)是否存在 StatusWith<Status>
和 StatusWith<StatusWith<T>>
MONGO_STATIC_ASSERT_MSG(!isStatusOrStatusWith<T>,
"StatusWith<Status> and StatusWith<StatusWith<T>> are banned.");
其中 MONGO_STATIC_ASSERT_MSG
是 static_assert
的封裝,static_assert
在編譯期間判斷第一個(gè)參數(shù)對(duì)應(yīng)的表達(dá)式是否為 true
榜贴,如果為 false
則報(bào)錯(cuò)豌研。
在這里妹田,表達(dá)式為 !isStatusOrStatusWith<T>
,該表達(dá)式是如何在編譯期計(jì)算的呢鹃共?
// Using extern constexpr to prevent the compiler from allocating storage as a poor man's c++17
// inline constexpr variable.
// TODO delete extern in c++17 because inline is the default for constexpr variables.
template <typename T>
extern constexpr bool isStatusWith = false;
template <typename T>
extern constexpr bool isStatusWith<StatusWith<T>> = true;
template <typename T>
extern constexpr bool isStatusOrStatusWith =
std::is_same<T, mongo::Status>::value || isStatusWith<T>;
extern constexpr 不太明白其作用
通過(guò) is_same
和 存在特化的isStatusWith
即可在編譯期間完成類型的判斷鬼佣。
TagType
TagType 的定義如下:
struct TagTypeBase {
protected:
TagTypeBase() = default;
};
// `TagType` is used as a placeholder type in parameter lists for `enable_if` clauses. They
// have to be real parameters, not template parameters, due to MSVC limitations.
class TagType : TagTypeBase {
TagType() = default;
friend StatusWith;
};
因此 TagType
內(nèi)部沒(méi)有具體的功能,因此其功能在其存在上霜浴,如:
template <typename Alien>
StatusWith(Alien&& alien,
typename std::enable_if_t<std::is_convertible<Alien, T>::value, TagType> = makeTag(),
typename std::enable_if_t<!std::is_same<Alien, T>::value, TagType> = makeTag())
: StatusWith(static_cast<T>(std::forward<Alien>(alien))) {}
其中晶衷,enable_if_t
和 is_convertible
與 is_same
配合使用,利用SFINAE的特性阴孟,生成符合要求的構(gòu)造函數(shù)晌纫,如這里的要求為:
-
Alien
必須能夠轉(zhuǎn)換成T
-
Alien
必須不能為T
transform
StatusWith
實(shí)現(xiàn)了 transform
函數(shù),如果StatusWith
為值永丝,那么對(duì)該值應(yīng)用一個(gè)函數(shù)锹漱,如果 StatusWith
為錯(cuò)誤狀態(tài),則以該錯(cuò)誤狀態(tài)創(chuàng)建新的 StatusWith
并返回慕嚷。
template <typename F>
StatusWith<std::invoke_result_t<F&&, T&>> transform(F&& f) & {
if (_t)
return {std::forward<F>(f)(*_t)};
else
return {_status};
}
其中哥牍,invoke_result_t
的原型如下:
template<class F, class... ArgTypes>
class invoke_result;
template< class F, class... ArgTypes>
using invoke_result_t = typename invoke_result<F, ArgTypes...>::type;
F
為可調(diào)用的類型,invoke_result
返回該調(diào)用類型以 ArgTypes
的參數(shù)類型調(diào)用的時(shí)候的返回值的類型喝检。這里使用 F&&
是為了做完美轉(zhuǎn)發(fā)的用途嗅辣。
此外,該函數(shù)后面存在一個(gè) &
挠说,這是函數(shù)引用限定澡谭,可以為 &
和 &&
,引用限定可以讓成員函數(shù)只能被左值對(duì)象調(diào)用或者只能被右值對(duì)象調(diào)用损俭。
總結(jié)
StatusWith
適合在某容易出現(xiàn)錯(cuò)誤的計(jì)算序列中存儲(chǔ)中間的計(jì)算結(jié)果译暂,可能有利于設(shè)計(jì)好的錯(cuò)誤處理。