이전 게시물의 몇 가지 아이디어를 결합한 다음은 GCC4.6에서 테스트 한 중첩 구조에서도 작동하는 솔루션입니다.
template <typename T, typename ...Args>
std::array<T, sizeof...(Args) + 1> make_array(T && t, Args &&... args)
{
static_assert(all_same<T, Args...>::value, "make_array() requires all arguments to be of the same type."); // edited in
return std::array<T, sizeof...(Args) + 1>{ std::forward<T>(t), std::forward<Args>(args)...};
}
이상하게도 반환 값을 rvalue 참조로 만들 수 없으며 중첩 된 구성에는 작동하지 않습니다. 어쨌든, 여기 테스트가 있습니다 :
auto q = make_array(make_array(make_array(std::string("Cat1"), std::string("Dog1")), make_array(std::string("Mouse1"), std::string("Rat1"))),
make_array(make_array(std::string("Cat2"), std::string("Dog2")), make_array(std::string("Mouse2"), std::string("Rat2"))),
make_array(make_array(std::string("Cat3"), std::string("Dog3")), make_array(std::string("Mouse3"), std::string("Rat3"))),
make_array(make_array(std::string("Cat4"), std::string("Dog4")), make_array(std::string("Mouse4"), std::string("Rat4")))
);
std::cout << q << std::endl;
// produces: [[[Cat1, Dog1], [Mouse1, Rat1]], [[Cat2, Dog2], [Mouse2, Rat2]], [[Cat3, Dog3], [Mouse3, Rat3]], [[Cat4, Dog4], [Mouse4, Rat4]]]
(마지막 출력을 위해 pretty-printer를 사용하고 있습니다.)
실제로,이 구조의 유형 안전을 향상 시키십시오. 모든 유형이 동일해야합니다. 한 가지 방법은 위에서 편집 한 정적 어설 션을 추가하는 것입니다. 다른 방법은 make_array
다음과 같이 유형이 동일한 경우 에만 활성화 하는 것입니다.
template <typename T, typename ...Args>
typename std::enable_if<all_same<T, Args...>::value, std::array<T, sizeof...(Args) + 1>>::type
make_array(T && t, Args &&... args)
{
return std::array<T, sizeof...(Args) + 1> { std::forward<T>(t), std::forward<Args>(args)...};
}
어느 쪽이든 variadic all_same<Args...>
유형 특성 이 필요합니다 . 그것은 여기에서 일반화이다 std::is_same<S, T>
(부패가 혼합 수 있도록하는 것이 중요합니다 T
, T&
, T const &
등) :
template <typename ...Args> struct all_same { static const bool value = false; };
template <typename S, typename T, typename ...Args> struct all_same<S, T, Args...>
{
static const bool value = std::is_same<typename std::decay<S>::type, typename std::decay<T>::type>::value && all_same<T, Args...>::value;
};
template <typename S, typename T> struct all_same<S, T>
{
static const bool value = std::is_same<typename std::decay<S>::type, typename std::decay<T>::type>::value;
};
template <typename T> struct all_same<T> { static const bool value = true; };
참고 make_array()
복사 - 임시 (충분한 최적화 플래그와 함께!)하는 컴파일러에 의해 반환이를 rvalue로 치료를 허용하거나 최적화 멀리, 그리고 std::array
컴파일러가 최적의 시공 방법을 선택 무료입니다, 그래서 집계 유형이 .
마지막으로, make_array
이니셜 라이저를 설정할 때 복사 / 이동 구성을 피할 수 없습니다 . 따라서 std::array<Foo,2> x{Foo(1), Foo(2)};
복사 / 이동은 없지만 auto x = make_array(Foo(1), Foo(2));
인수가 전달 될 때 두 개의 복사 / 이동이 make_array
있습니다. 난 당신이 도우미에 전적으로 가변 인자 초기화 목록을 통과 할 수 없기 때문에 당신이 그 개선 할 수 있다고 생각하지 않습니다 과 를 추론 유형 및 크기 - 프리 프로세서가 있던 경우에 sizeof...
가변 인수 기능을, 아마도 그 완료,하지만 수 핵심 언어 내에서.