2013-05-16 3 views
30

템플릿 매개 변수로 다른 컨테이너를 사용하여 템플릿 클래스 (어댑터)를 어떻게 선언 할 수 있습니까? 예를 들어, I 클래스 선언 할 필요가 :템플릿 컨테이너가있는 템플릿 클래스

template<typename T, typename Container> 
class MyMultibyteString 
{ 
    Container buffer; 
    ... 
}; 

을 그리고 벡터를 기반으로 내 그것을 원한다. 그것을 어떻게 하드 정의합니까? (누군가가 그러한 선언문을 작성하는 것을 막기 위해 MyMultibyteString<int, vector<char>>).

또한, 이러한 건설 구현하는 방법 : 컨테이너 템플릿 인수를 통과하지 않고

MyMultibyteString<int, std::vector> mbs; 

합니다. 이것은 당신이 쓸 수있는 것

template<typename T, template <typename, typename> class Container> 
//     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
class MyMultibyteString 
{ 
    Container<T, std::allocator<T>> buffer; 
    // ... 
}; 

:

답변

59

당신은 템플릿 템플릿 매개 변수를 사용해야합니다

다음
MyMultibyteString<int, std::vector> mbs; 

는 컴파일 live example이다. 수 위를 기록하는 또 다른 방법 : 여기

template<typename T, 
    template <typename, typename = std::allocator<T>> class Container> 
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
class MyMultibyteString 
{ 
    Container<T> buffer; // <== No more need to specify the second argument here 
    // ... 
}; 

그리고는 해당 live example입니다.

주의해야 할 점은 템플릿 템플릿 매개 변수 선언에있는 인수의 수와 유형이 정확히 일치해야하는 해당 클래스 템플릿의 정의에있는 인수의 수와 유형과 일치해야한다는 것입니다 템플리트 인수 중 일부 매개 변수에 기본값이있을 수 있다는 사실에 관계없이.

예를 들어 std::allocator<T>이 기본값이지만 두 번째 요소는 std::allocator<T>이더라도 the class template std::vector accepts two template parameters (요소 유형과 할당 자 유형)입니다. 이 때문에, 당신은하지 쓰기 수 :

template<typename T, template <typename> class Container> 
//        ^^^^^^^^ 
//        Notice: just one template parameter declared! 
class MyMultibyteString 
{ 
    Container<T> buffer; 
    // ... 
}; 

// ... 

MyMultibyteString<int, std::vector> mbs; // ERROR! 
//      ^^^^^^^^^^^ 
//      The std::vector class template accepts *two* 
//      template parameters (even though the second 
//      one has a default argument) 
이것은 당신이 때문에 std::vector 달리, 템플릿 템플릿 매개 변수로 모두 std::setstd::vector을 받아 들일 수 하나의 클래스 템플릿을 쓸 수 없다는 것을 의미

, the std::set class template accepts three template parameters. 이 문제를 해결하기 위해

+0

정말 대단한 철저한 대답. –

+0

@ScottJones : 유용하다는 것을 알았 기 때문에 기쁩니다 :) –

+3

@ScottJones 귀하의 진술에 대해서 :'이것은 std :: set와 std :: vector'를 모두 받아 들일 수있는 하나의 단일 클래스 템플릿을 작성할 수 없다는 것을 의미합니다. variadic 템플릿은 문제를 해결합니까? http://stackoverflow.com/a/20499809/2436175 – Antonio

2

또 다른 방법은 가변 인자 템플릿을 사용하는 것입니다 위 의견 제안 그것과 당신은 어떤 컨테이너를 사용할 수 있으며 여기 된 구현입니다 :

template<template <typename... Args> class Container,typename... Types> 
class Test 
{ 
    public: 
    Container<Types...> test; 

}; 
int main() 
{ 
    Test<std::vector,int> t; 
    Test<std::set,std::string> p; 
    return 0; 
} 
관련 문제