我正在研究一個小型圖書館,我需要做的事情之一是將訪問者應用於某些數據並返回結果。爲什麼`std :: common_type_t <std :: ostream&,std :: ostream&>`等於`std :: ostream`而不是`std :: ostream&`?
在一些較舊的C++代碼中,訪問者預計會聲明一個typedef return_type
。例如,boost::static_visitor
這樣做。
在較新的代碼中,所有這些訪問者都被棄用。在C++ 14中,您通常可以使用decltype(auto)
,但我正在嘗試使用類似std::common_type
的東西來做到這一點,以便我可以在C++ 11中執行此操作。
我試着簡單地將std::common_type
的示例實現反向移植到C++ 11並使用它來計算返回類型。
#include <ostream>
#include <type_traits>
// decay_t backport
template <typename T>
using decay_t = typename std::decay<T>::type;
// common_type backport
template <typename T, typename... Ts>
struct common_type;
template <typename T>
struct common_type<T> {
using type = decay_t<T>;
};
template <typename T1, typename T2>
struct common_type<T1, T2> {
using type = decay_t<decltype(true ? std::declval<T1>() : std::declval<T2>())>;
};
// TODO: Is this needed?
/*
template <typename T>
struct common_type<T, T> {
using type = T;
};
*/
template <typename T1, typename T2, typename T3, typename... Ts>
struct common_type<T1, T2, T3, Ts...> {
using type = typename common_type<typename common_type<T1, T2>::type, T3, Ts...>::type;
};
template <typename T, typename... Ts>
using common_type_t = typename common_type<T, Ts...>::type;
// static_assert(std::is_same<common_type_t<std::ostream &, std::ostream &>, std::ostream &>::value, "This is what I expected!");
static_assert(std::is_same<common_type_t<std::ostream &, std::ostream &>, std::ostream>::value, "Hmm...");
int main() {}
使用「可能實現」的時候什麼「應該」的std::common_type_t<std::ostream&, std::ostream&>
的結果是我得到一些意想不到的結果?它應該不是std::ostream &
?如果沒有,那麼爲什麼gcc 5.4.0
和clang 3.8.0
認爲它是std::ostream
?
注意:當我在C++ 14中使用「真實」std::common_type_t
時,我仍然得到std::ostream
而不是std::ostream &
。
正在專精std::common_type
這樣std::common_type_t<T, T>
總是T
有效的方法嗎?它似乎在我的程序中運行良好,但感覺像是一個黑客。
相關:http://stackoverflow.com/q/21975812/2069064,但是'common_type'不會給你引用,因爲悲傷的臉。 – Barry
謝謝...所以我想我不應該在那裏使用'std :: declval'?我應該使用'decltype(true?std :: forward(std :: declval ()):std :: forward (std :: declval ())''?我想這實際上很棘手... –