これはC++ 1zで行うことができます。あなたはあなたが尋ねたように、既に定義を求め、すべての演算子を持つタプルを作成するためにtie_as_tuple
を使用することができ、今
struct anything {
template<class T> operator T()const;
};
namespace details {
template<class T, class Is, class=void>
struct can_construct_with_N:std::false_type {};
template<class T, std::size_t...Is>
struct can_construct_with_N<T, std::index_sequence<Is...>,
std::void_t< decltype(T{(void(Is),anything{})...}) >>:
std::true_type
{};
}
template<class T, std::size_t N>
using can_construct_with_N=details::can_construct_with_N<T, std::make_index_sequence<N>>;
namespace details {
template<std::size_t Min, std::size_t Range, template<std::size_t N>class target>
struct maximize: std::conditional_t<
maximize<Min, Range/2, target>{} == (Min+Range/2)-1,
maximize<Min+Range/2, (Range+1)/2, target>,
maximize<Min, Range/2, target>
>{};
template<std::size_t Min, template<std::size_t N>class target>
struct maximize<Min, 1, target>: std::conditional_t<
target<Min>{},
std::integral_constant<std::size_t,Min>,
std::integral_constant<std::size_t,Min-1>
>{};
template<std::size_t Min, template<std::size_t N>class target>
struct maximize<Min, 0, target>:
std::integral_constant<std::size_t,Min-1>
{};
template<class T>
struct construct_searcher {
template<std::size_t N>
using result = ::can_construct_with_N<T, N>;
};
template<class T, std::size_t Cap=4>
using construct_arity = details::maximize< 0, Cap, details::construct_searcher<T>::template result >;
template<typename T>
constexpr auto tie_as_tuple_impl(std::integral_constant<size_t, 1>, T&& t){
auto&& [a] = t;
return std::tie(a);
}
template<typename T>
constexpr auto tie_as_tuple_impl(std::integral_constant<size_t, 2>, T&& t){
auto&& [a,b] = t;
return std::tie(a,b);
}
template<typename T>
constexpr auto tie_as_tuple_impl(std::integral_constant<size_t, 3>, T&& t){
auto&& [a,b,c] = t;
return std::tie(a,b,c);
}
template<size_t S, typename T>
constexpr auto tie_as_tuple(T&& t){
return tie_as_tuple_impl(std::integral_constant<size_t, S>{}, std::forward<T>(t));
}
}
template<typename T>
constexpr auto tie_as_tuple(T&& t){
constexpr size_t S = details::construct_arity<std::decay_t<T>>::value;
return details::tie_as_tuple<S>(std::forward<T>(t));
}
:this答えに基づか、私がコンセプトの、次の証明を用意しました。
demo
Iはtie_as_tuple_impl
のいくつかのオーバーロード、構造体の各要素数のいずれかを準備しなければならなかったが、それは、構造体の要素の数を直線的にスケール注意。 C++ 14では
が同様のソリューションを可能性がありますmagic_get
だが、それはその点に注意して、より多くの情報のためhereを参照してください。
メンバー以外の友人以外のオペレータが過負荷になることはありませんか?それはあなたがしたいことに最もよく聞こえます。 –
標準のC++は_reflection_をサポートしていません(まだ)。 –
そして、C++の単純な複雑さのために、私は包括的に役立つ方法で追加することは難しいと思います。別の方法として、http://stackoverflow.com/a/40564415/120163 –