전화했는데 구현할 수 있는 ',' C++14 앨리어스가 템플리트를 make_integer_sequence 익스포트를 단순화됩니다 클래스의 템플리트를 'integer_sequence'.
template< class T, T... I> struct integer_sequence
{
typedef T value_type;
static constexpr size_t size() noexcept { return sizeof...(I) ; }
};
template< class T, T N>
using make_integer_sequence = integer_sequence< T, 0,1,2, ... ,N-1 >; // only for illustration.
'' 도우미 '구조' make_helper make_integer_sequence 구현하기 위해 필요하다.
template< class T , class N >
using make_integer_sequence = typename make_helper<T,N>::type;
template< class T, T N, T... I >
struct make_helper
{
typedef typename mpl::if_< T(0) == N,
mpl::identity< integer_sequence<T,I...> >,
make_helper< T, N-1, N-1,I...>
>::type;
};
'난' 이 테스트하려면 make_integer_sequence 브라운아저씨의 주요 기능:
int main()
{
#define GEN(z,n,temp) \
typedef make_integer_sequence< int, n > BOOST_PP_CAT(int_seq,n) ;
BOOST_PP_REPEAT(256, GEN, ~);
}
이 프로그램을 통해 컴파일했습니다 mgcc 4.8.0 쿼드-코어 tmi5 시스템에 RAM 에 8GBs. 4 초 컴파일 성공 했다.
하지만, 내가 언제 매크로를 GEN 바꿨다.
int main() {
#define GEN(z,n,temp) \
typedef make_integer_sequence< int, n * 4 > BOOST_PP_CAT(int_seq, n) ;
BOOST_PP_REPEAT(256, GEN, ~ );
}
컴필레이션 실패한 출력 및 오류 메시지: >. 가상 메모리 지친.
누군가 이 오류 및 설명할 수 있는 원인은 무엇이었습니까?
편집:
내가 이 간편화된 테스트하려면:
int main()
{
typedef make_integer_sequence< int, 4096 > int_seq4096;
}
그런 다음 함께 성공적으로 컴파일됨 mgcc 4.8.0 - 포툠판 깊이까지의 = 65536.
그러나 이 두 번째 테스트:
int main()
{
typedef make_integer_sequence< int, 16384 > int_seq16384;
}
그 결과, 그리고 GCC 와 컴파일하십시오 4.8.0 않았다 - 포툠판 깊이까지의 = 65536 error:: >, 가상 메모리 지친.
그래, 내 질문은 템플리트를 깊이형 인스턴스 감소, 어떻게 해야 합니까?
감사합니다. 쿠르.
// using aliases for cleaner syntax
template<class T> using Invoke = typename T::type;
template<unsigned...> struct seq{ using type = seq; };
template<class S1, class S2> struct concat;
template<unsigned... I1, unsigned... I2>
struct concat<seq<I1...>, seq<I2...>>
: seq<I1..., (sizeof...(I1)+I2)...>{};
template<class S1, class S2>
using Concat = Invoke<concat<S1, S2>>;
template<unsigned N> struct gen_seq;
template<unsigned N> using GenSeq = Invoke<gen_seq<N>>;
template<unsigned N>
struct gen_seq : Concat<GenSeq<N/2>, GenSeq<N - N/2>>{};
template<> struct gen_seq<0> : seq<>{};
template<> struct gen_seq<1> : seq<0>{};
이것은 기본적으로 해킹 수립하였습니다 나를 Xeo& # 39 의 솔루션: , 부탁이네 업보테 셰로 감사하는 커뮤니티 위키 경우 - 있다.
// based on http://stackoverflow.com/a/17426611/410767 by Xeo
namespace std // WARNING: at own risk, otherwise use own namespace
{
template <size_t... Ints>
struct index_sequence
{
using type = index_sequence;
using value_type = size_t;
static constexpr std::size_t size() noexcept { return sizeof...(Ints); }
};
// --------------------------------------------------------------
template <class Sequence1, class Sequence2>
struct _merge_and_renumber;
template <size_t... I1, size_t... I2>
struct _merge_and_renumber<index_sequence<I1...>, index_sequence<I2...>>
: index_sequence<I1..., (sizeof...(I1)+I2)...>
{ };
// --------------------------------------------------------------
template <size_t N>
struct make_index_sequence
: _merge_and_renumber<typename make_index_sequence<N/2>::type,
typename make_index_sequence<N - N/2>::type>
{ };
template<> struct make_index_sequence<0> : index_sequence<> { };
template<> struct make_index_sequence<1> : index_sequence<0> { };
}
유라유라테이코쿠:
이 " magic"; # 39 의 Xeo& _merge_and_renumber 선언 '의 솔루션) 은' ('concat' 자신의 코드) 과 두 개의 매개변수를 정확히 알 수 있고, 스페실리사션 효과적으로 각자의 매개변수입니다 팩
유형 이름 '에서'. '는' 유형.
구조체입니다 make_index_sequence . _merge_and_renumber< make_index_sequence< N/2> 유형 유형 이름,, n - 유형 이름 make_index_sequence< N/2> ::type>;;
빨리, 빨리, 빨리, 빨리 & & & &,,, 미리 오류:
invalid use of incomplete type 'struct std::_merge_and_renumber<std::make_index_sequence<1ul>, std::index_sequence<0ul> >'
내가 찾은 불필요한 반복 버전 '의' 매우 빠르고 깊이형 구축현 make_index_sequence. 내 PC 에서 N = 1 048 576, 2 개 포함) 이 함께 컴파일 한다. (PC: Centos 6.4 x86, 8 Gb RAM, O2 - - - 표준용량 = c++0x gcc-4.4.7 tmi5, 벽).
#include <cstddef> // for std::size_t
template< std::size_t ... i >
struct index_sequence
{
typedef std::size_t value_type;
typedef index_sequence<i...> type;
// gcc-4.4.7 doesn't support `constexpr` and `noexcept`.
static /*constexpr*/ std::size_t size() /*noexcept*/
{
return sizeof ... (i);
}
};
// this structure doubles index_sequence elements.
// s- is number of template arguments in IS.
template< std::size_t s, typename IS >
struct doubled_index_sequence;
template< std::size_t s, std::size_t ... i >
struct doubled_index_sequence< s, index_sequence<i... > >
{
typedef index_sequence<i..., (s + i)... > type;
};
// this structure incremented by one index_sequence, iff NEED-is true,
// otherwise returns IS
template< bool NEED, typename IS >
struct inc_index_sequence;
template< typename IS >
struct inc_index_sequence<false,IS>{ typedef IS type; };
template< std::size_t ... i >
struct inc_index_sequence< true, index_sequence<i...> >
{
typedef index_sequence<i..., sizeof...(i)> type;
};
// helper structure for make_index_sequence.
template< std::size_t N >
struct make_index_sequence_impl :
inc_index_sequence< (N % 2 != 0),
typename doubled_index_sequence< N / 2,
typename make_index_sequence_impl< N / 2> ::type
>::type
>
{};
// helper structure needs specialization only with 0 element.
template<>struct make_index_sequence_impl<0>{ typedef index_sequence<> type; };
// OUR make_index_sequence, gcc-4.4.7 doesn't support `using`,
// so we use struct instead of it.
template< std::size_t N >
struct make_index_sequence : make_index_sequence_impl<N>::type {};
//index_sequence_for any variadic templates
template< typename ... T >
struct index_sequence_for : make_index_sequence< sizeof...(T) >{};
// test
typedef make_index_sequence< 1024 * 1024 >::type a_big_index_sequence;
int main(){}
'-' Here you are 없습니다.
typedef typename mpl::if_< T(0) == N,
mpl::identity< integer_sequence<T> >,
make_helper< T, N, N-1,I...>
>::type;
특히:
typedef typename mpl::if_< T(0) == N,
mpl::identity< integer_sequence<T> >,
make_helper< T, N-1, N-1,I...>
>::type;
다음으로 ',' t be # 39, 첫 번째 분기로의 shouldn& integer_sequence< T> integer_sequence<, T, I. > 아니라, ','.
typedef typename mpl::if_< T(0) == N,
mpl::identity< integer_sequence<T, I...> >,
make_helper< T, N-1, N-1,I...>
>::type;
있어야 할 수 있을 만큼 원본 코드가 전달하십시오 컴파일하십시오.
템플릿 메타프로그래밍 너회의 골을 기록할 때 일반적으로 '심각한' 주 '템플리트를 깊이를 렉시한테서 해야 할' 인스턴스 아래에있어. 이 문제가 있을 경우 생각할 수 있는 방법을 상상하는 무한 스레드할 컴퓨터: 각각의 독립적인 계산 끝에 함께 자체 스레드할 관심용 관용으로충만하신 제공하십시오 셔플 오프하도록 단행했다. You have a, O (1) '.' 등 깊이 있는 몇 가지 작업을 시행하십시오 개확장: 저들이요 활용
일반적으로 볼 수 있는 충분한 근거가 있는 '의 대수 깊이까지의 때문에 900' 깊이 '2 ^ 900' 뭔가 다른 크기의 구조 및 브레이크 이번이 처음이다. (공정하게, 지정하십시오. 가능성이 더 크기 구조를 '2' 는 90 일이 다른 계층의 ^ 10).
여기 다른 약간 더 일반적인 변형 [셰로] (https://stackoverflow.com/a/17426611/4618482) & # 39, 임의의 대수 오토메이티드 's' 를 제공하는 make_integer_sequence 추상형데이터타입. 이 작업은 ',' std::integral_constant 사용하여 방지하기 위해 인수 部门从 템플리트를 띄게 " 템플리트를 parameter". 오류:.
template<typename Int, Int... Ints>
struct integer_sequence
{
using value_type = Int;
static constexpr std::size_t size() noexcept
{
return sizeof...(Ints);
}
};
template<std::size_t... Indices>
using index_sequence = integer_sequence<std::size_t, Indices...>;
namespace
{
// Merge two integer sequences, adding an offset to the right-hand side.
template<typename Offset, typename Lhs, typename Rhs>
struct merge;
template<typename Int, Int Offset, Int... Lhs, Int... Rhs>
struct merge<
std::integral_constant<Int, Offset>,
integer_sequence<Int, Lhs...>,
integer_sequence<Int, Rhs...>
>
{
using type = integer_sequence<Int, Lhs..., (Offset + Rhs)...>;
};
template<typename Int, typename N>
struct log_make_sequence
{
using L = std::integral_constant<Int, N::value / 2>;
using R = std::integral_constant<Int, N::value - L::value>;
using type = typename merge<
L,
typename log_make_sequence<Int, L>::type,
typename log_make_sequence<Int, R>::type
>::type;
};
// An empty sequence.
template<typename Int>
struct log_make_sequence<Int, std::integral_constant<Int, 0>>
{
using type = integer_sequence<Int>;
};
// A single-element sequence.
template<typename Int>
struct log_make_sequence<Int, std::integral_constant<Int, 1>>
{
using type = integer_sequence<Int, 0>;
};
}
template<typename Int, Int N>
using make_integer_sequence =
typename log_make_sequence<
Int, std::integral_constant<Int, N>
>::type;
template<std::size_t N>
using make_index_sequence = make_integer_sequence<std::size_t, N>;
데모: [콜이루] (http://coliru.stacked-crooked.com/a/a3e426cc235ec2d7)
간단한 구축상의 O (N). 그러나 나의 응용 프로그램이 그리웠댔지 아닐 수 있는 함수를 호출하기 위한 대규모 N 만 t 이상의 인덱스된 인수만, 쉐퍼드도 wouldn& # 39, 받게 인수에 약 10. # 39 의 난, t) 의 멤버여야 haven& 접수됨 integer_sequence. I& # 39, m 이 사용하는 표준 라이브러리 구축 및 누킹 기대합니다:)
template <typename T, T... ints>
struct integer_sequence
{ };
template <typename T, T N, typename = void>
struct make_integer_sequence_impl
{
template <typename>
struct tmp;
template <T... Prev>
struct tmp<integer_sequence<T, Prev...>>
{
using type = integer_sequence<T, Prev..., N-1>;
};
using type = typename tmp<typename make_integer_sequence_impl<T, N-1>::type>::type;
};
template <typename T, T N>
struct make_integer_sequence_impl<T, N, typename std::enable_if<N==0>::type>
{ using type = integer_sequence<T>; };
template <typename T, T N>
using make_integer_sequence = typename make_integer_sequence_impl<T, N>::type;