반응형
C ++ 11에서 N 요소 constexpr 배열 만들기
안녕하세요 저는 C ++ 11을 배우고 있습니다. 예를 들어 constexpr 0에서 n 배열을 만드는 방법이 궁금합니다.
n = 5;
int array[] = {0 ... n};
그래서 배열은 {0, 1, 2, 3, 4, 5}
C ++ 14에서는 constexpr
생성자와 루프를 사용하여 쉽게 수행 할 수 있습니다 .
#include <iostream>
template<int N>
struct A {
constexpr A() : arr() {
for (auto i = 0; i != N; ++i)
arr[i] = i;
}
int arr[N];
};
int main() {
constexpr auto a = A<4>();
for (auto x : a.arr)
std::cout << x << '\n';
}
질문에 대한 주석의 답변과 달리 컴파일러 확장 없이도이 작업을 수행 할 수 있습니다.
#include <iostream>
template<int N, int... Rest>
struct Array_impl {
static constexpr auto& value = Array_impl<N - 1, N, Rest...>::value;
};
template<int... Rest>
struct Array_impl<0, Rest...> {
static constexpr int value[] = { 0, Rest... };
};
template<int... Rest>
constexpr int Array_impl<0, Rest...>::value[];
template<int N>
struct Array {
static_assert(N >= 0, "N must be at least 0");
static constexpr auto& value = Array_impl<N>::value;
Array() = delete;
Array(const Array&) = delete;
Array(Array&&) = delete;
};
int main() {
std::cout << Array<4>::value[3]; // prints 3
}
@Xeo의 훌륭한 아이디어를 기반으로 , 다음은 배열을 채울 수있는 접근 방식입니다.
constexpr std::array<T, N> a = { fun(0), fun(1), ..., fun(N-1) };
- 어디에
T
어떤 문자 유형 (단지이다int
또는 다른 유효한 비 형 템플릿 매개 변수 유형)뿐만 아니라double
, 또는std::complex
(C에서 + 14 이후) - 기능
fun()
은 어디에 있습니까?constexpr
- 이는
std::make_integer_sequence
C ++ 14부터 지원 되지만 오늘날에는 g ++ 및 Clang 모두로 쉽게 구현됩니다 (답변 끝에있는 라이브 예제 참조). - 나는 GitHub (Boost License) 에서 @JonathanWakely 의 구현을 사용합니다.
다음은 코드입니다.
template<class Function, std::size_t... Indices>
constexpr auto make_array_helper(Function f, std::index_sequence<Indices...>)
-> std::array<typename std::result_of<Function(std::size_t)>::type, sizeof...(Indices)>
{
return {{ f(Indices)... }};
}
template<int N, class Function>
constexpr auto make_array(Function f)
-> std::array<typename std::result_of<Function(std::size_t)>::type, N>
{
return make_array_helper(f, std::make_index_sequence<N>{});
}
constexpr double fun(double x) { return x * x; }
int main()
{
constexpr auto N = 10;
constexpr auto a = make_array<N>(fun);
std::copy(std::begin(a), std::end(a), std::ostream_iterator<double>(std::cout, ", "));
}
C ++ 14 integrated_sequence 또는 불변 index_sequence 사용
#include <iostream>
template< int ... I > struct index_sequence{
using type = index_sequence;
using value_type = int;
static constexpr std::size_t size()noexcept{ return sizeof...(I); }
};
// making index_sequence
template< class I1, class I2> struct concat;
template< int ...I, int ...J>
struct concat< index_sequence<I...>, index_sequence<J...> >
: index_sequence< I ... , ( J + sizeof...(I) )... > {};
template< int N > struct make_index_sequence_impl;
template< int N >
using make_index_sequence = typename make_index_sequence_impl<N>::type;
template< > struct make_index_sequence_impl<0> : index_sequence<>{};
template< > struct make_index_sequence_impl<1> : index_sequence<0>{};
template< int N > struct make_index_sequence_impl
: concat< make_index_sequence<N/2>, make_index_sequence<N - N/2> > {};
// now, we can build our structure.
template < class IS > struct mystruct_base;
template< int ... I >
struct mystruct_base< index_sequence< I ... > >
{
static constexpr int array[]{I ... };
};
template< int ... I >
constexpr int mystruct_base< index_sequence<I...> >::array[] ;
template< int N > struct mystruct
: mystruct_base< make_index_sequence<N > >
{};
int main()
{
mystruct<20> ms;
//print
for(auto e : ms.array)
{
std::cout << e << ' ';
}
std::cout << std::endl;
return 0;
}
output: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
업데이트 : std :: array를 사용할 수 있습니다.
template< int ... I >
static constexpr std::array< int, sizeof...(I) > build_array( index_sequence<I...> ) noexcept
{
return std::array<int, sizeof...(I) > { I... };
}
int main()
{
std::array<int, 20> ma = build_array( make_index_sequence<20>{} );
for(auto e : ma) std::cout << e << ' ';
std::cout << std::endl;
}
#include <array>
#include <iostream>
template<int... N>
struct expand;
template<int... N>
struct expand<0, N...>
{
constexpr static std::array<int, sizeof...(N) + 1> values = {{ 0, N... }};
};
template<int L, int... N> struct expand<L, N...> : expand<L-1, L, N...> {};
template<int... N>
constexpr std::array<int, sizeof...(N) + 1> expand<0, N...>::values;
int main()
{
std::cout << expand<100>::values[9];
}
부스트 전처리기를 사용하면 매우 간단합니다.
#include <cstdio>
#include <cstddef>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/comma_if.hpp>
#define IDENTITY(z,n,dummy) BOOST_PP_COMMA_IF(n) n
#define INITIALIZER_n(n) { BOOST_PP_REPEAT(n,IDENTITY,~) }
int main(int argc, char* argv[])
{
int array[] = INITIALIZER_n(25);
for(std::size_t i = 0; i < sizeof(array)/sizeof(array[0]); ++i)
printf("%d ",array[i]);
return 0;
}
OUTPUT: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
boost::mpl::range_c<int, 0, N>
문서를 사용해보십시오 .
참조 URL : https://stackoverflow.com/questions/19019252/create-n-element-constexpr-array-in-c11
반응형
'developer tip' 카테고리의 다른 글
C #을 사용하여 Excel 파일에서 데이터를 읽는 방법 (0) | 2020.12.15 |
---|---|
Twitter Bootstrap 테이블 셀에 collapse.js 사용 [거의 완료] (0) | 2020.12.15 |
셀레늄 드라이버에 대한 사용자 에이전트 변경 (0) | 2020.12.15 |
Lombok @Builder 및 JPA 기본 생성자 (0) | 2020.12.15 |
Lambda 함수 내에서 직접 Thread # sleep ()을 호출 할 수없는 이유는 무엇입니까? (0) | 2020.12.15 |