2012-04-13 3 views
0

나는이 큐 클래스를 가지고있다. 실제로 같은 문제를 겪고있는 몇 개의 큐 - 긴 복사본을 가진 타입으로 컴파일하면 성능이 떨어질 것이다. - 큐는 푸시/팝 중에 잠겨있어 잠긴다. , 경합의 기회가 커집니다. 개발자가 (포인터 대신) 10MB 버퍼 클래스로 컴파일하려고하면 클래스가 컴파일되지 않으면 유용 할 것입니다.포인터가 아닌 템플릿 클래스에 대한 예외가 발생합니까?

템플릿 매개 변수를 기본 클래스 또는 다른 유형으로 제한하는 쉬운 방법이없는 것처럼 보입니다.

매개 변수가 클래스 인스턴스에 대한 포인터가 아닌 경우 내 클래스가 컴파일되지 않도록 사용할 수 있습니까?

+2

당신은 아마 다음, 이동 ctors를 지원해야한다. 10MB 버퍼 클래스를 옮기는 것은 전혀 비싸지 않아도됩니다. – MSalters

답변

5

여러 가지 방법으로이 작업을 수행 할 수 있습니다. 다른 대답은 당신이 static_assert (가능하면 C++ 11/Boost에서 가능하지만 roll your own)를 사용하여 수행 할 수 있다고 지적했기 때문에 실제로 포인터인지 여부를 확인하고 크기에만 의존하지 않는 것이 좋습니다. 당신은 자신의 롤 또는 (도 사용할 수 in C++11)를 existing trait를 사용하여 어떤 시스템을 사용중인에 따라 할 수 있습니다 :

template <typename T> 
struct is_pointer { 
    enum { value = 0 }; 
}; 

template <typename T> 
struct is_pointer<T*> { 
    enum { value = 1 }; 
}; 

template <typename T> 
struct container { 
    static_assert(is_pointer<T>::value, "T must be a pointer"); 
    void push(const T&); 
    T pop(); 
}; 

struct foo {}; 

int main() { 
    container<foo*> good; 
    container<foo> fail; 
} 

을하지만 더 큰 점을 제기한다. 귀하의 요구 사항이 오직 사물을 가리키고 있다면, 왜 그런 템플릿 매개 변수를 해석하지 않으시겠습니까? 예 : 당신의 컨테이너를 만드십시오 :

template <typename T> 
struct container { 
    void push(const T*); 
    T *pop(); 
}; 

사람들이 처음에 포인터가 아닌 타입을 지정할 수있게 하시겠습니까?

template <typename T> 
struct container; 

template <typename T> 
struct container<T*> { 
    void push(const T*); 
    T *pop(); 
}; 

struct foo {}; 

int main() { 
    container<foo*> good; 
    container<foo> fail; 
} 

를이 여전히 명시 적으로 요구하기 : 만이 아니라 예를 들면, 비 대한 포인터를 구현 그냥 포인터 타입의 컨테이너를 전문으로 할 수있는 static_assert 길을 가고 싶지 않는 경우에 마지막으로

포인터를 입력하면 비 포인터 유형에 대해 컴파일 시간 오류가 발생하지만, static_assert 또는 유형이 포인터인지 여부를 판별 할 필요가 없습니다.

+0

이것은 오래된 질문이지만 C++ 11에서는 std :: is_pointer를 추가했습니다 http://www.cplusplus.com/reference/type_traits/is_pointer/ – Jameshobbs

0

변형 된 어설 션을 사용할 수 있습니다 (많은 구현에서 google을 사용). BOOST_STATIC_ASSERT(sizeof(T) <= sizeof(void*))과 같은 것이 트릭을해야합니다.

+0

T가 작기 때문에 사소한 복사본 생성자가 있다는 것을 의미하지는 않습니다. – Flexo

+0

흠, 네 말이 맞아. 그러나 유형이 예를 들어 원시 유형인지 여부를 판별하는 특성 도우미 클래스도 있습니다. sizeof 테스트 대신이를 대체 할 수 있습니다. – zvrba

0

예, static_assert를 사용하여 수행 할 수 있습니다. 예 :

2

"매개 변수가 클래스 인스턴스에 대한 포인터가 아닌 경우 내 클래스가 컴파일되지 않도록 사용할 수 있습니까?"

아니 bodge

:하지만,

template<class T> 
class MyContainer 
{ 
public: 
    void AllMemberFunctions(T* in){} 
    void OnlyAcceptTStars(T* in){} 

}; 

사용자가 개최되는 유형을 정의하고 함수는 수락하거나 해당 유형에 대한 포인터를 처리합니다.

(또는 사용자의 부분에 대한 몇 가지 정보를 가정하고 문제에 대해 잊지 않는 것을 STL 않습니다.)

관련 문제