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


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...)여기서는 ...추상 선언자의 일부가 아니므 int로 void(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.