2009-12-14 3 views
7

나는 템플릿 기반 클래스 A < T, int>와 두 개의 typedef A < 문자열, 20> 및 A < 문자열, 30>을 가지고 있습니다. < 문자열, 20>에 대한 생성자를 재정의하려면 어떻게해야합니까? 다음은 작동하지 않습니다생성자의 C++ 템플릿 전문화

template <typename T, int M> class A; 
typedef A<std::string, 20> one_type; 
typedef A<std::string, 30> second_type; 


template <typename T, int M> 
class A { 
public: 
    A(int m) {test= (m>M);} 

    bool test; 

}; 


template<> 
one_type::one_type() { cerr << "One type" << endl;} 

내가 다른 클래스하지 않는 뭔가를 클래스에게 < 표준 : : 문자열, 20> 싶습니다. 생성자 A : A (int)를 변경하지 않고 이것을 어떻게 할 수 있습니까?

+0

를? – GManNickG

+0

질문이 명확하지 않습니다. BTW, one_type에는 빈 생성자가 없으며 int 매개 변수가있는 생성자가 있습니다. – Drakosha

답변

1

현재 접근 방식으로는 접근 할 수 없습니다. one_type은 특정 템플릿 전문의 별칭이므로 템플릿에있는 코드를 가져옵니다. 당신이 one_type 특정 코드를 추가하려면

,이 같은 전문화의 서브 클래스로 선언해야합니다 :

class one_type: 
    public A<std::string>, 20> 
    { 
    one_type(int m) 
     : A<str::string, 20>(m) 
    { 
     cerr << "One type" << endl; 
    } 
    }; 
+0

생각. 생성자를 멤버 함수로 특수화 할 수 없으면 왜 안되는지에 대한 인수를 제공 할 수 있습니까? –

+0

아래 답변 됨 : –

6

이 가정 당신의 정말 공개적으로 액세스 할 수 A::test에 대한 의미, 당신을

#include <iostream> 


template <int M> 
struct ABase 
{ 
    ABase(int n) : test_(n > M) 
    {} 

    bool const test_; 
}; 


template <typename T, int M> 
struct A : ABase<M> 
{ 
    A(int n) : ABase<M>(n) 
    {} 
}; 


template <typename T> 
A<T, 20>::A(int n) 
    : ABase<20>(n) 
    { std::cerr << "One type" << std::endl; } 

킥 타이어 :

int main(int argc, char* argv[]) 
{ 
    A<int, 20> a(19); 
    std::cout << "a:" << a.test_ << std::endl; 
    A<int, 30> b(31); 
    std::cout << "b:" << b.test_ << std::endl; 
    return 0; 
} 
같은 것을 할 수
+1

좋은 답변, 타입 시스템이있는 견과류 : P –

8

당신이 할 수없는 유일한 일은 typedef을 사용하여 생성자를 정의하는 것입니다.

template<> class A<string,20> { 
public: 
    A(const string& takethistwentytimes) { cerr << "One Type" << std::endl; } 
}; 
: 당신이 전체 A<string,20> 클래스를 전문으로 할 필요를

template<> A<string,20>::A(int){} 

당신이 일반 A보다 다른 생성자를 가지고 A<string,20>을 원하는 경우 : 그 이외에,이 같은 A<string,20> 생성자를 전문으로한다고

0

방법에 대해 :

template<typename T, int M, bool dummy = (M > 20) > 
class A { 
public: 
    A(int m){ 
     // this is true 
    } 

}; 

template<typename T, int M> 
class A<T,M,false> { 
public: 
    A(int m) { 
    //something else 
    } 
}; 
0

최고

template <typename T, int M> class A; 
typedef A<std::string, 20> one_type; 
typedef A<std::string, 30> second_type; 

template <typename T, int M> 
class A { 
private: 
    void cons_helper(int m) {test= (m>M);} 
public: 
    A(int m) { cons_helper(m); } 

    bool test; 
}; 

template <> 
void one_type::cons_helper(int) { cerr << "One type" << endl;} 
0

이 늦게 조금있을 수 있습니다,하지만 당신은 c++11에 액세스 할 수있는 경우 당신은에 SFINAE를 사용할 수 있습니다 솔루션은 내가이 상황이 "생성자 도우미"기능을 사용하는 것입니다 위해 마련 할 수있었습니다 당신이 원하는 바로 달성 : 당신은 클래스가 할려고 무엇

template <class = typename std::enable_if< 
    std::is_same<A<T,M>, A<std::string, 20>>::value>::type // Can be called only on A<std::string, 20> 
    > 
    A() { 
    // Default constructor 
    } 

Working example