2017-12-08 3 views
8

개념으로 식별되는 특정 클래스 세트를 각각 적용 할 수있는 두 개 (또는 그 이상)의 템플릿이 있습니다. 두 개의 템플릿이 동일한 이름을 가질 수있게하려면 특수화해야합니다.C++ 개념 및 템플릿 전문화; 사용자 친화적 인 컴파일러 오류를 얻는 방법

template< typename T > 
struct pin_in { static_assert(always_false<T>::value, . . .); }; 

template< is_pin_in T > 
struct pin_in<T> . . . 

template< is_pin_in_out T > 
struct pin_in<T> . . . 

전문화 중 하나가 일치하면 정상적으로 작동합니다. 일치하지 않으면 기본 템플릿이 선택되고 어설 션 오류가 발생합니다. 메커니즘이 작동합니다. 나는 개념을 좋아한다!

그러나 오류 메시지 (GCC 7.2.0)가 어서션을 가리 킵니다. 어떻게 든 기본 템플릿을 선택하지 않도록 할 수 있으므로 템플릿이 인수 클래스와 일치하지 않는다는 오류 메시지가 나타납니다.

+0

정적 어설 션에 메시지 (두 번째 인수)를 추가 할 수없는 이유는 무엇입니까? –

+0

물론 나는 그것이있다. . . 그러나 기본 오류 메시지는 여전히 원인이 된 행이 아니라 어설 션을 가리 킵니다. –

+0

때때로 컴파일러는 Object_ 인스턴스화 및 _ 여기에서 _required의 형식으로 백 트레이스를 추가합니다. 여기서는 인스턴스화가 발생한 위치를 가리 킵니다. –

답변

2

만세, 나는 해결책을 발견! 당신이 필요로하는 것은 기본 템플릿을 제약하는 것입니다 :

template <class T> 
    requires is_pin_in<T> || is_pin_in_out<T> 
struct pin_in {}; 


template <is_pin_in T> 
struct pin_in<T> {}; 

template <is_pin_in_out T> 
struct pin_in<T> {}; 

그리고 당신은 좋은 진단 메시지를 얻을 :

<source>: In function 'auto test()': 
29 : <source>:29:16: error: template constraint failure 
    pin_in<char> a; 
       ^
29 : <source>:29:16: note: constraints not satisfied 
7 : <source>:7:24: note: within 'template<class T> concept const bool is_pin_in<T> [with T = char]' 
constexpr concept bool is_pin_in = std::is_same_v<T, int>; 
         ^~~~~~~~~ 
7 : <source>:7:24: note: 'std::is_same_v' evaluated to false 
9 : <source>:9:24: note: within 'template<class T> concept const bool is_pin_in_out<T> [with T = char]' 
constexpr concept bool is_pin_in_out = std::is_same_v<T, unsigned>; 
         ^~~~~~~~~~~~~ 
9 : <source>:9:24: note: 'std::is_same_v' evaluated to false 
Compiler exited with result code 1 

, 내 메시지가 일부 더미 제약입니다,하지만 당신은 얻을 점

+0

니스! 구조에 개념입니다. –

+0

그러나 하나의 작은 문제가 있습니다. 즉,이 솔루션은 나중에 기본 템플릿을 변경하지 않고도 is_pin_foo라고하는 특수화를 추가 할 수 없다는 의미에서 닫힙니다. 그러나 받아 들일 수있는 클래스의 태그 유형은이를 해결할 수 있습니다. 그러나 그것은 역의 문제를 야기 할 수 있습니다 : lateron으로 작성된 데코레이터 템플릿은 기존 클래스에 마커를 추가해야합니다. 그것이 요구에 열거하지 않는 한 ... 나는 이걸 가지고 놀거야! –

+0

@WoutervanOoijen 그냥 'pin_in'에 맞는 개념을 만들 것입니다. 예 : '템플릿 constexpr 개념 bool is_any_pin_in = is_pin_in || is_pin_in_out ' – bolov

0

과부하 해결에서 기본 템플릿을 제거하려면 std :: enable_if를 사용해보십시오. 이 같은 뭔가 :

template< typename T > 
struct pin_in<typename std::enable_if<false>::type> {}; 

template< is_pin_in T > 
struct pin_in<typename std::enable_if<true>::type><T> . . . 

template< is_pin_in_out T > 
struct pin_in<typename std::enable_if<true>::type><T> . . . 
+0

그건 내가 좋아하는 일종이지만, 첫 번째 pin_in에 오류가 있습니다. 'pin_in은 클래스 템플릿이 아닙니다' –