2014-01-07 1 views
1

요소 유형에 기본 생성자가없는 경우 모든 중복 요소가 포함 된 템플릿 배열을 구성하는 방법이 있습니까?기본 생성자가없는 중복 요소의 템플릿 배열

template<typename T, int n> struct Array { 
    template<typename... Args> explicit Array(const T& arg1, Args... args) 
     : m_a{arg1, args...} { } 
    static Array<T,n> all(const T& value) { 
     Array<T,n> ar; // error: use of deleted function 'Array<TypeWithoutDefault, 10>::Array()' 
     for (int i=0; i<n; i++) 
      ar.m_a[i] = value; 
     return ar; 
    } 
    T m_a[n]; 
}; 

struct TypeWithoutDefault { 
    TypeWithoutDefault(int i) : m_i(i) { } 
    int m_i; 
}; 

int main() { 
    // works fine 
    Array<TypeWithoutDefault,2> ar1 { TypeWithoutDefault{1}, TypeWithoutDefault{2} }; 
    (void)ar1; 
    // I want to construct an Array of n elements all with the same value. 
    // However, the elements do not have a default constructor. 
    Array<TypeWithoutDefault,10> ar2 = Array<TypeWithoutDefault, 10>::all(TypeWithoutDefault(1)); 
    (void)ar2; 
    return 0; 
} 
+1

좋아하면'repeat' 기능이 필요

나는 다음을 시도했다. 내 대답 좀 봐 : [T는 기본 constructible 경우 std :: array 우아하게하는 방법?] (http://stackoverflow.com/questions/18497122/how-to-initialize-stdarrayt-n-elegantly-if -t-is-not-default-constructible) – Nawaz

+0

그게 효과가 있는지 알려주세요. 그렇지 않은 경우 수정하고 답변으로 게시합니다. – Nawaz

+0

감사합니다. 제 질문은 불행히도 여러 사람이 지적한 중복 질문이었습니다. @ Nawaz와 @ Jarod42의 대답은 모두 매우 적절합니다. 'index_sequence'와'make_index_sequence'의 간결한 구조는 매우 좋습니다. – Hugues

답변

1

으로 문제를 해결할 수 다음과 같습니다 :

#if 1 // Not in C++11 

template <std::size_t ...> struct index_sequence {}; 

template <std::size_t I, std::size_t ...Is> 
struct make_index_sequence : make_index_sequence<I - 1, I - 1, Is...> {}; 

template <std::size_t ... Is> 
struct make_index_sequence<0, Is...> : index_sequence<Is...> {}; 

#endif 

namespace detail 
{ 
    template <typename T, std::size_t ... Is> 
    constexpr std::array<T, sizeof...(Is)> create_array(T value, index_sequence<Is...>) 
    { 
     // cast Is to void to remove the warning: unused value 
     return {{(static_cast<void>(Is), value)...}}; 
    } 
} 

template <std::size_t N, typename T> 
constexpr std::array<T, N> create_array(const T& value) 
{ 
    return detail::create_array(value, make_index_sequence<N>()); 
} 

그래서 테스트 :

struct TypeWithoutDefault { 
    TypeWithoutDefault(int i) : m_i(i) { } 
    int m_i; 
}; 

int main() 
{ 
    auto ar1 = create_array<10>(TypeWithoutDefault(42)); 
    std::array<TypeWithoutDefault, 10> ar2 = create_array<10>(TypeWithoutDefault(42)); 

    return 0; 
} 
+0

'{{(static_cast (Is), value) ...}};'에서 캐스트를 사용할 필요가 없습니다. 당신은'{{(Is, value) ...}};'를 사용할 수 있습니다. 계속 간단하게! – Nawaz

관련 문제