我的解决方案:)) 用 gcc 4.6.4 -std=c++0x 编译
主要思想是,对于任何 'i' 和 0,1,2,...n-1 (其中 n > i) (0 ^ i), ( 1 ^ i ), ... (j ^ i) .. . , ( (n-1) ^ i ) -- 是唯一的序列,只有 'i' 处的值位置为零。
这不是 O(1) 解决方案,O( log(n)) 解决方案。但它基于 C++14 make_index_sequence。iff 编译器确实在 O(1) 编译 make_index_sequence,所以我的解决方案也变成了 O(1)。
#include <cstddef>
#include <iostream>
#include <type_traits>
namespace mpl
{
// C++14 index_sequence struct
template< int ... i >
struct index_sequence
{
typedef index_sequence type;
typedef int value_type;
static constexpr std::size_t size()noexcept{ return sizeof...(i); }
};
namespace details
{
#if 1
template< int s, typename T, typename U> struct concate_c;
template<int s, int ...i, int ...j>
struct concate_c< s, index_sequence<i...>, index_sequence<j...> >
: index_sequence<i..., (j + s ) ... > {};
template< int s, typename T, typename U> struct concate : concate_c< s, typename T::type, typename U::type > {};
template< int n>
struct make_index_sequence : concate< n / 2,
make_index_sequence< n / 2 >,
make_index_sequence< n - n / 2 >
>{};
#else
template< typename T, typename U> struct concate_c;
template< int ...i, int ...j>
struct concate_c< index_sequence<i...>, index_sequence<j...> >
: index_sequence<i..., (j + sizeof...(i) ) ... > {};
template< typename T, typename U> struct concate : concate_c< typename T::type, typename U::type > {};
template< int n>
struct make_index_sequence : concate<
make_index_sequence< n / 2 >,
make_index_sequence< n - n / 2 >
>{};
#endif
template<> struct make_index_sequence<0> : index_sequence<>{};
template<> struct make_index_sequence<1> : index_sequence<0>{};
} // namespace details
template< int n> struct make_index_sequence : details::make_index_sequence<n> {};
template< typename ...Args>
struct make_index_sequence_for : make_index_sequence< sizeof...(Args) > {};
// helper for at_c, I - index_sequence,
template< typename I, typename ...p >
struct at_ch;
// only zero index have `type`.
template< int i, typename T> struct id{};
template< typename T>struct id<0,T>{ typedef T type;};
// based from all parameters.
template< typename ...T> struct base_all : T... {};
template< int ... i, typename ...p>
struct at_ch< index_sequence<i...>, p... >
{
struct base : base_all< id<i,p> ... > {};
typedef typename base::type type;
};
// 0 1 2 3 4 5 6 7 8 9
// 0: 0 1 2 3 4 5 6 7 8 9
// 1: 1 0 3 2 5 4 7 6 9 8
template< int i, typename I>
struct xor_index_sequence;
template< int i, int ...k>
struct xor_index_sequence< i, index_sequence<k...> > : index_sequence< (k xor i) ... > {};
template< int i, typename ...T>
struct at_c: at_ch<
typename xor_index_sequence< i,
typename make_index_sequence< sizeof...(T)> ::type
>::type,
T...
> {};
}
int main()
{
typedef mpl::at_c< 2, int, double , float >::type G;
static_assert( std::is_same<G, float>::value ,"!");
return 0;
}