“……”토큰의 의미는 무엇입니까? 즉, 매개 변수 팩의 이중 생략 연산자


110

gcc의 현재 구현 된 새로운 C ++ 11 헤더를 탐색하는 동안 "......"토큰을 발견했습니다. 다음 코드가 [ideone.com을 통해] 잘 컴파일 되는지 확인할 수 있습니다 .

template <typename T>
struct X
{ /* ... */ };

template <typename T, typename ... U>
struct X<T(U......)> // this line is the important one
{ /* ... */ };

그렇다면이 토큰의 의미는 무엇입니까?

편집 : 질문 제목의 "......"이 "..."로 잘린 것 같습니다. 정말 "......"을 의미했습니다. :)


힌트 : ...뒤에 ....
Alexandre C.

5
그렇지 더 같다 U...다음에 .... 그럼에도 불구하고 매우 이상합니다.
edA-qa mort-ora-y 2011

1
참고 : 이는 <functional><type_traits>에서 찾을 수 있으며 항상 템플릿 매개 변수 내부의 함수 인수 목록 컨텍스트에서 찾을 수 있습니다 .
Potatoswatter 2011

제목에 갇히게하는 유일한 방법은 사이에 공백을 두는 것뿐입니다. 독자들에게 더 명확 해지기를 바랍니다.
Matthieu M.

@Matthieu M .: 감사합니다, 훨씬 낫습니다!
Vitus

답변:


79

그 이상 함의 모든 인스턴스는 일반 단일 줄임표의 경우와 쌍을 이룹니다.

  template<typename _Res, typename... _ArgTypes>
    struct _Weak_result_type_impl<_Res(_ArgTypes...)>
    { typedef _Res result_type; };

  template<typename _Res, typename... _ArgTypes>
    struct _Weak_result_type_impl<_Res(_ArgTypes......)>
    { typedef _Res result_type; };

  template<typename _Res, typename... _ArgTypes>
    struct _Weak_result_type_impl<_Res(_ArgTypes...) const>
    { typedef _Res result_type; };

  template<typename _Res, typename... _ArgTypes>
    struct _Weak_result_type_impl<_Res(_ArgTypes......) const>
    { typedef _Res result_type; };

내 생각에 이중 줄임표는 의미가 비슷하다는 것입니다 _ArgTypes..., .... 즉, 가변 템플릿 확장에 이어 C 스타일의 varargs 목록이 이어집니다.

여기에 그 이론을 뒷받침 하는 테스트 가 있습니다 ... 저는 우리가 사상 최악의 의사 연산자로 새로운 승자가 있다고 생각합니다.

편집 : 이것은 준수하는 것으로 보입니다. §8.3.5 / 3에서는 매개 변수 목록을 구성하는 한 가지 방법을 다음과 같이 설명합니다.

매개 변수 선언 목록 opt ... opt

따라서 이중 줄임표는 매개 변수 팩으로 끝나는 매개 변수 선언 목록과 다른 줄임표로 구성됩니다.

쉼표는 순전히 선택 사항입니다. §8.3.5 / 4는

구문이 정확하고 "..."가 추상 선언자의 일부가 아닌 경우 ", ..."는 "..."와 동의어입니다.

이것은 이다 , 추상적 - 선언자 내에서 [편집] 하지만, 요하네스은 매개 변수 선언 내에서 추상 선언자 언급하는 것이 좋은 지적을합니다. 왜 그들이 "파라미터 선언의 일부"라고 말하지 않았는지, 왜 그 문장이 단지 유익한 메모가 아닌지 궁금합니다…

또한 va_begin()in <cstdarg>은 varargs 목록 앞에 매개 변수 가 필요하므로 f(...)C ++에서 특별히 허용 하는 프로토 타입 은 쓸모가 없습니다. C99와의 상호 참조는 일반 C에서는 불법입니다. 그래서 이것은 가장 기괴합니다.

사용법 참고

요청에 따라 다음은 이중 줄임표 의 데모 입니다.

#include <cstdio>
#include <string>

template< typename T >
T const &printf_helper( T const &x )
    { return x; }

char const *printf_helper( std::string const &x )
    { return x.c_str(); }

template< typename ... Req, typename ... Given >
int wrap_printf( int (*fn)( Req... ... ), Given ... args ) {
    return fn( printf_helper( args ) ... );
}

int main() {
    wrap_printf( &std::printf, "Hello %s\n", std::string( "world!" ) );
    wrap_printf( &std::fprintf, stderr, std::string( "Error %d" ), 5 );
}

네, 맞습니다. T (U ..., ...) 그러나 잘 컴파일됩니다. 아마도 그들은 약간의 공간을 절약하고 싶었을 것입니다. :)
Vitus

1
그러나 그것은 무엇을 의미할까요? 컴파일러는 _ArgTypes가 끝나고 일부 "추가"매개 변수가 시작되는 위치를 어떻게 알 수 있습니까?
Bo Persson 2011

12
@Bo Persson : std::is_function's value는 함수가 C varargs 1 인 경우에도 true 여야하며 T (U ...)가 이러한 함수와 일치 하지 않기 때문에이 광기가 필요합니다. 예를 들어 int f (int, char, ...)는 T (U ......)를 T = int, U = {int, char} 및 "..."varargs 토큰과 정확히 일치시킵니다.
Vitus 2011

4
"이것은 이다 >가 같은 매개 변수 유형 목록의 마지막 매개 변수의 추상적 선언자의 일부가 아닌 의미 - 추상적 - 선언자 내". 예를 들어, void (int...)여기서는 ...추상 선언자의 일부가 아니므 intvoid(int, ...). 작성 void(T...)하고 T템플릿 매개 변수 팩인 ...경우 추상 선언자의 일부이므로 void(T, ...).
Johannes Schaub-litb 2011

2
"또한, <cstdarg>의 va_begin ()은 varargs 목록 앞에 매개 변수가 필요하므로 C ++에서 특별히 허용하는 프로토 타입 f (...)은 쓸모가 없습니다." -어떤 인수가 전달되었는지 알고 싶은 경우에만 쓸모가 없습니다. f(...)템플릿 메타 프로그래밍에서 대체 함수 오버로드로 많이 사용되며,이 정보가 필요하지 않은 경우 (그리고 함수가 실제로 호출되지 않는 경우).

4

vs2015에서 쉼표를 구분하는 것은 템플릿 버전에서 필수적입니다.

    template <typename T, typename ... U>
    struct X<T(U...,...)> {};// this line is the important one

인스턴스화의 예는 다음과 같습니다.

    X<int(int...)> my_va_func;

안부, FM.


나도이 사실을 알아 차 렸지만 여전히 발생합니다. developercommunity.visualstudio.com/content/problem/437260/…의 버그 보고서 .
egyik

알아 둘만 한. 이에 대한 표준에 대한 언급이나 인용이 있습니까?
Red.Wave

.سلام ببخشید نمیدانم
egyik

이것은 공개 포럼입니다. 사람들이 당신의 생각을 읽게하십시오. PLZ는 비공개 메시지에 대한 기본 언어를 유지합니다. سپاس.
Red.Wave

자 그리고 나서. 저는 표준에 대한 전문가가 아닙니다. 다른 사람들이 위에서 자세히 다루었다고 생각합니다. 누군가가 Microsoft 문제 보고서에 대해 언급하고 싶다면 우선 순위를 높일 수 있습니다. 이 보고서는 VC ++가 지원하지 않는 것을 허용하는 clang과 gcc를 보여 주므로 우리는 아마도 상당히 강력한 기반에 있다고 생각합니다.
egyik
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.