2012-11-26 2 views
8
템플릿 initializer_list 건설을 지원

, 내가 합리적으로 쉽게 initializer_list 생성자를 위임 할 수 있습니다 보인다 예를 들면.이 선택적으로 어쩌면 포장 용기

int main(int argc, char* argv[]) { 

    holder<std::vector<int>> y{1,2,3}; 
    return EXIT_SUCCESS; 
} 

는하지만 꽤 분명 'INT', 또는 중첩 된 VALUE_TYPE의 형식 정의가없는 다른 유형으로 T 작동하지 않습니다. 그래서, T는 중첩 된 value_type typedef를 정의하고 std :: initializer_list에서 생성 가능하지 않으면 initializer_list 생성자가 생성되지 않도록하기 위해 enable_if 또는 유사한 트릭을 사용하고 싶습니다.

holder(typename std::enable_if<std::is_constructible<T, std::initializer_list<typename T::value_type>>::value, std::initializer_list<typename T::value_type>>::type values) 
    : t_(values) {} 

하나를 : 컴파일러 (내 경우 ++ 3.1 그 소리가) 여전히 T는 int이며 잘못된 T :: VALUE_TYPE 걸려 넘어 때문에,

나는 다음과 같은 시도,하지만 여전히 작동하지 않습니다 개념을 표현하는 방법에 대한 생각은 "T가 value_type typedef를 갖고 T :: value_type의 initializer_list에서 생성 가능한 경우에만 T의 value_type에 대한 이니셜 라이저 목록 생성자에 대해이 템플릿을 제공합니다".

+0

는'initializer_list' 올바른 값에 의해 전달하거나 일부 참조 형식으로 전달해야합니까? ('&&'?) –

+0

@MartinBa :'std :: initializer_list'에 대한 값에 의한 전달이 정확하고 (권장 됨). –

+0

'initializer_list'는 포인터와 크기를 포함하기 때문에 값으로 전달하는 것이 좋습니다. 데이터 자체는 복사되지 않습니다. –

답변

4

SFINAE는 템플릿 매개 변수 하위 항목 (SFINAE의 S)에서만 작동합니다. 다음 작품 :

template<typename T> 
struct holder { 
    T t_; 

    holder() : 
     t_() {} 

    template<typename U = T> 
    holder(typename std::enable_if<std::is_constructible<U, std::initializer_list<typename U::value_type>>::value, 
    std::initializer_list<typename U::value_type>>::type values) 
    : t_(values) {} 

}; 

당신이 컴파일러 오류로 이어지는 다음 전체 클래스 (귀하의 예제에서) 유형 int 인스턴스화 될 템플릿 기능을 사용하지 않은 경우. 당신이 여분의 템플릿 매개 변수를 사용하는 경우 함수 서명 좋네요 만들 수

참고 :

template<typename U = T, class = typename std::enable_if<std::is_constructible<U, std::initializer_list<typename U::value_type>>::value, bool>::type> 
    holder(std::initializer_list<typename U::value_type> values) 
    : t_(values) {} 
+0

흥미 롭습니다. 그러나 꽤 효과적이지 않습니다. 'holder > y = {1, 2, 3}'가 올바르게 작동하지만 적어도 제 컴파일러에서는 개정 된 생성자 서명을 사용할 수 없습니다. 1 개의 인수가 필요하지만 3이 제공되었습니다 ' – acm

+2

enable_if를 삭제할 수없고'template holder (std :: initializer_list 값)'? –

+0

@ VaughnCato는 더 잘 작동하는 것 같습니다. – acm