私は小さなライブラリに取り組んでいます。私がする必要があることの1つは、訪問者をデータに適用して結果を返すことです。なぜ `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にバックポートし、それを使用して戻り値の型を特定しました。 std::common_type_t<std::ostream&, std::ostream&>
の結果は
#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::ostream &
でなければなりませんか?そうでない場合、なぜgcc 5.4.0
とclang 3.8.0
の両方がstd::ostream
だと思いますか?
注:実際のstd::common_type_t
をC++ 14で使用すると、まだstd::ostream
で、std::ostream &
ではなくなります。
が常に有効な方法であるようにstd::common_type
を特化していますか?私のプログラムでうまくいくようですが、ハックのように感じます。
関連:http://stackoverflow.com/q/21975812/2069064、しかし 'common_type'はあなたに悲しい顔があるので参考にしません。 – Barry
ありがとうございます。だから私は 'std :: declval'をそこに使ってはいけないと思いますか? 'decltype(true?std :: forward(std :: declval ()):std :: forward (std :: decl())')を使うべきですか?私はこれが実際にはかなりトリッキーだと思う...'テンプレート をmini_decay_t = conditional_t < のstd :: is_lvalue_reference ::値を使用して: –