15

함수 템플릿 오버로드 사이의 모호성을 해결할 때 부분 순서가 수행됩니다 (일부 설명은 here 참조). 해당 웹 사이트에서, 우리는 또한 배울 넥타이의 경우정확히 "후행 매개 변수 팩"

, 그 하나의 함수 템플릿은 후행 매개 변수를 팩을 가지고 있으며, 다른 하나는 보다 더 전문적인 것으로 간주됩니다,하지 생략 된 매개 변수를 사용하여 하나의 작업을 수행하는 경우 빈 매개 변수 팩이있는 것.

정확히 후행 매개 변수 팩이 무엇인지 궁금합니다. 어떤 경우에

template<class ...> struct tuple { /* ... */ }; 

template<class T, class...Ts> void foo(tuple<T,Ts...>); 

template<class T, class...Ts> void bar(T, Ts...); 

어떤 것인가 그리고 그 이유는 무엇입니까? 참고 또한 그 소리는 foo가 후행 매개 변수 팩이 없음을 암시

template<class T> void f(tuple<T>); 

template<class T, class...Ts> void f(tuple<T,Ts...>); 

int main() 
{ f(tuple<int>()); } // ambiguous call? 

모호한 생각한다.

+1

롤,이 두 가지 의견은 서로 모순입니다! 그래서 여기서 논의 할 것이 있습니다. – Walter

+0

@ Jarod42 그래서 '후행 매개 변수 팩'은 템플릿 매개 변수가 아닌 함수 인수를 나타냅니다. – Walter

+0

실제로 clang과 gcc는 동의하지 않습니다 [데모] (http://coliru.stacked-crooked.com/a/6f67a0a696424a56). – Jarod42

답변

7

이것은 resolution이 초안 C++ 17 표준에 최근에 투표 된 CWG1395입니다. 다음은 [temp.deduct.partial]에 첨가 하였다 :

... 함수 템플릿 F는 적어도 함수 서식 G 반대로 같은 전문되고, [] 만약 G 후행 파라미터 팩이 있으면 어떤 경우에는 F에 해당 매개 변수가없고 F에 후행 매개 변수 팩이없는 경우 FG보다 더 전문화되어 있습니다.

표준은 "후행 매개 변수 팩"이 의미하는 것을 명시 적으로 정의하지는 않지만이 용어가 사용되는 기존 문맥에서 판단 할 때 가장 오른쪽 매개 변수로 나타나는 템플릿 매개 변수 팩을 참조합니다. 템플릿 매개 변수 목록 :

template<class T, class... U> struct X; 
//    ^^^^^^^^^^ 

또는 함수 매개 변수 목록의 맨 오른쪽 매개 변수로 표시되는 함수 매개 변수 팩 :

template<class T, class... U> void y(T, U...); 
//          ^^^^ 

현재 초안은 여전히이 포함되어 있습니다 [temp.deduct.type]에서 오래된 예 :

template<class T, class... U> void f(T, U...); 
template<class T> void f(T); 

f(&i); // error: ambiguous 

이 표준 결함 보고서는 몇 년 동안 주변되었습니다, 그리고 GCCClang 모두 그것의 해상도를 구현했습니다. 그들은 위의 예가 f의 두 번째 오버로드의 유효한 호출이라는 것에 모두 동의합니다.

여기서 GCC와 Clang은 결함 해결의 범위에 속합니다. 이는 제안 된 표준 문구를 포함하도록 최근에 업데이트 된 것이므로 이해할 수 있습니다. 당신의 예에서 팩은 함수 매개 변수 목록으로 확장 된 것이 아니라, 함수 매개 변수 형식의 템플릿 인수 목록에 : g의 두 번째 오버로드의 유효한 전화로

template<class T, class... U> void g(tuple<T, U...>); 
template<class T> void g(tuple<T>); 

g(tuple<int>{}); 

GCC 취급이; Clang은이를 모호한 것으로 취급합니다.Clang의 정확성은 후행 템플릿 매개 변수 팩을 포함 할 것인지, 아니면 함수 매개 변수 팩의 후행만을 포함 할 것인지에 따라 달라질 수 있습니다. 두 컴파일러가 C<int> 다음 예제 클래스 템플릿 C의 두 번째 부분 특수화를 참조하는 동의

참고 :

template<class...> struct C; 

template<class T, class... U> struct C<T, U...> {}; 
template<class T> struct C<T> {}; 

이 연타의 모순처럼 보인다 인해 일부 주문에 대한 표준 규칙 클래스 템플릿 전문은 함수 템플릿의 부분 순서에 따라 정의됩니다. CWG1432을 참조하십시오.

+2

CWG1395의 해상도가 최신 작업 초안에 투표되었습니다. [N4619] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4619.html)를 참조하십시오. 나는 이것이 cppreference 텍스트의 출처라고 생각합니다. 불행히도, 그것은 1432를 다루는 것 같지 않습니다, 그리고 그것이 제가보기에는 유일한 문제는 아닙니다. 더 재미있게하려면 [이 토론] (https://chat.stackoverflow.com/rooms/130228/discussion-between-bogdan-and-barry)을 확인하십시오. – bogdan

+0

MSVC는 GCC와 동의합니다 : [두 경우 모두'template '버전의'template '버전이 이에 상응합니다] (http://rextester.com/FEKSB40747). 솔직히 말해서 나는 Clang이했던 것보다'g()'버전을 더 빨리 해결한다는 것에 놀랐다. –

+0

뒤 따르지 않는 매개 변수 팩이 있습니까? –

0

Trailing은 "끝"을 의미합니다.

template <typename T1, typename... Ts> 
void foo(); 

//^Ts... is trailing here 

이것은 C++ 질문,하지만 영어 문제되지 않습니다 :

트레일 링 매개 변수 팩

템플릿 매개 변수 목록의 끝에있는 매개 변수 팩입니다.

+4

그래 ... 어쩌면 더 단순한 우주에서, 밝기가 가득한 팩 중 하나일지도 모릅니다. 꾸러미는 반짝 반짝 빛나는 실체입니다 ... 서로 경주하고, 누가 후행인지 알기 위해 노력합니다. 물론 표준 블랙홀 주위의 궤도에있는 모든 이들이 진정으로 후행 할 수는 없습니다. 이제는 더 혼란 스럽습니다. – bogdan

+1

코드에는'Ts ... '가 없습니다. – Walter

+0

@Walter :'template ' –

관련 문제