2017-11-14 2 views
12

오늘 나는 clang의 C++ 17 지원 페이지를 읽었습니다. 나는 이상한 것을 알았다. 기능 템플릿 템플릿 매개 변수를 호환 가능한 인수로 일치 시키려면 스위치를 통해 활성화해야하므로 (P0522R0)은 부분으로 표시됩니다. 그들의 주 says :P0522R0 위반 코드는 어떻게됩니까?

결함 보고서의 해상도를 임에도 불구하고,이 기능은 연타 4 -frelaxed - 템플릿 템플릿 인수를 모든 언어 버전에서 기본적으로 사용되며, 플래그를 명시 적으로 활성화 할 수 있습니다 표준을 변경하면 템플릿 부분 정렬에 대한 해당 변경 사항이 없어 합리적이고 이전에 유효한 코드에 대한 모호성 오류가 발생합니다. 이 문제는 곧 수정 될 것으로 예상됩니다.

이 기능을 활성화하면 어떤 종류의 구성이 중단됩니까? 왜 코드를 깨고 어떻게 할 수 있습니까? foo 두 가지가 하나 개의 템플릿 매개 변수를 사용하여 템플릿을 소요하지 때문에, 결함 해상도없이

template<template<typename> typename> 
struct Foo {}; 

template<typename, typename = void> 
struct Bar {}; 

Foo<Bar> unused; 

, unused이 잘못 형성 될 것이다 :

답변

12

는이 같은 코드를 가질 수 있습니다. 이 (아마도 SFINAE의 경우) :

template<template<typename> typename> 
void foo(); 

template<template<typename, typename> typename> 
void foo(); 

template<typename, typename = void> 
struct Bar {}; 

int main() { 
    foo<Bar>(); // ambiguous after resolution! 
} 

그런 다음 호출이 실패합니다! 문제는 부분 순서에 해당하는 변경 사항이 없으므로 두 후보 기능 모두 동일한 실행 가능성을 가지며 호출이 모호하다는 것입니다. 일부 코드가

template<class> struct Foo; 

template<template<class> class X, class T> 
struct Foo<X<T>> { /* ... */ }; 

template<template<class, class> class X, class T, class U> 
struct Foo<X<T, U>> { /* ... */ }; 

// etc., etc. 

Foo<std::vector<int>> 지금은 적절한 부분 순서를 수정하지 않고 잘못을 형성 : 부분 전문의 세트 템플릿 인수를 검사 예컨대을하고자 할 때

+0

아, 알겠습니다. 귀하의 예제에서, 나는'foo'의 두 번째 버전이 선택 될 것으로 기대합니다. –

+6

@Guillaume 네, 맞습니다. 그러나이 표준은 부분 순서로 텍스트를 가지고 있지 않다. ( – Rakete1111

+3

나는 이것에 관한 몇 가지 질문을 보았고, 심지어 이것에 대해서도 언급했다. 가장 일반적인 시나리오는 누군가가 컨테이너를 감싸고 있다고 생각한다. , 구체적으로'std :: vector'라고 부르며 그들은 또한 할당자를 가지고 있다는 것을 잊어 버린다. 그래서 당신은 [this] (https://wandbox.org/permlink/lYy8DNiF61ZH4Fmp)와 같은 코드로 끝난다. – AndyG

3

더 일반적인 시나리오입니다.

관련 문제