Programing

가변 템플릿의 맥락에서“…”토큰에 대한 규칙은 무엇입니까?

lottogame 2020. 8. 25. 19:19
반응형

가변 템플릿의 맥락에서“…”토큰에 대한 규칙은 무엇입니까?


C ++ 11에는 다음과 같은 가변 템플릿이 있습니다.

template< class T, class... Args >
unique_ptr<T> make_unique( Args&&... args )
{
    return unique_ptr<T>(new T(std::forward<Args>(args)...));
}

약간의 호기심이에 대해 다음과 같습니다 표현이 std::forward<Args>(args)...모두 사용 Args하고 args있지만, 단 하나의 ...토큰. 또한 std::forward하나의 템플릿 매개 변수와 하나의 인수 만 취하는 비가 변 템플릿 함수입니다. 이에 대한 구문 규칙은 무엇입니까 (대략)? 어떻게 일반화 할 수 있습니까?

또한 : 함수 구현에서 줄임표 ( ...)는 관심있는 표현의 끝에 있습니다. 템플릿 인수 목록과 매개 변수 목록에서 줄임표가 중간에있는 이유가 있습니까?


가변 템플릿 컨텍스트에서 줄임표 ...는 템플릿 매개 변수 팩이 표현식의 오른쪽에 나타나면 압축을 푸는 데 사용됩니다 (이 표현식 패턴 을 잠시 호출하십시오 ). 규칙은 의 왼쪽에있는 패턴...반복 된다는 것입니다 . 압축을 푼 패턴 ( 지금 표현식 이라고 부름 )은 쉼표로 구분 ,됩니다.

몇 가지 예를 통해 가장 잘 이해할 수 있습니다. 이 함수 템플릿이 있다고 가정합니다.

template<typename ...T>
void f(T ... args) 
{
   g( args... );        //pattern = args
   h( x(args)... );     //pattern = x(args)
   m( y(args...) );     //pattern = args (as argument to y())
   n( z<T>(args)... );  //pattern = z<T>(args)
}

이제이 함수를 T전달 하여 호출하면 {int, char, short}각 함수 호출이 다음과 같이 확장됩니다.

g( arg0, arg1, arg2 );           
h( x(arg0), x(arg1), x(arg2) );
m( y(arg0, arg1, arg2) );
n( z<int>(arg0), z<char>(arg1), z<short>(arg2) );

게시 한 코드 std::forward에서 n()함수 호출에 표시된 네 번째 패턴을 따릅니다 .

x(args)...y(args...)의 차이점에 유의하십시오 !


다음 ...과 같이 배열을 초기화하는 데 사용할 수도 있습니다.

struct data_info
{
     boost::any  data;
     std::size_t type_size;
};

std::vector<data_info> v{{args, sizeof(T)}...}; //pattern = {args, sizeof(T)}

다음으로 확장됩니다.

std::vector<data_info> v 
{ 
   {arg0, sizeof(int)},
   {arg1, sizeof(char)},
   {arg2, sizeof(short)}
};

public다음 예제와 같이 패턴에와 같은 액세스 지정자가 포함될 수도 있음을 깨달았습니다 .

template<typename ... Mixins>
struct mixture : public Mixins ...  //pattern = public Mixins
{
    //code
};

이 예에서 패턴은 다음과 같이 확장됩니다.

struct mixture__instantiated : public Mixin0, public Mixin1, .. public MixinN  

즉, 모든 기본 클래스 mixture에서 공개적으로 파생됩니다 .

도움이 되었기를 바랍니다.


다음은 GoingNative 2012에서 Andrei Alexandrescu의 "Variadic Templates are Funadic" 강연에서 발췌 한 것입니다. 가변 템플릿에 대한 좋은 소개를 위해 추천 할 수 있습니다.


가변 팩으로 할 수있는 일은 두 가지가 있습니다. sizeof...(vs)요소 수를 가져와 확장하기 위해 신청할 수 있습니다.

확장 규칙

Use            Expansion

Ts...          T1, ..., Tn
Ts&&...        T1&&, ..., Tn&&
x<Ts,Y>::z...  x<T1,Y>::z, ..., x<Tn,Y>::z
x<Ts&,Us>...   x<T1&,U1>, ..., x<Tn&,Un>
func(5,vs)...  func(5,v1), ..., func(5,vn)

Expansion proceeds inwards outwards. When expanding two lists in lock-step, they have to have the same size.

More examples:

gun(A<Ts...>::hun(vs)...);

Expands all Ts in the template argument list of A and then the function hun gets expanded with all vs.

gun(A<Ts...>::hun(vs...));

Expands all Ts in the template argument list of A and all vs as the function arguments for hun.

gun(A<Ts>::hun(vs)...);

Expands the function hun with Ts and vs in lock-step.

Note:

Ts is not a type and vs is not a value! They are aliases for a list of types/values. Either list may be potentially empty. Both obey only specific actions. So the following is not possible:

typedef Ts MyList;  // error!
Ts var;             // error!
auto copy = vs;     // error!

Expansion loci

Function arguments

template <typename... Ts>
void fun(Ts... vs)

Initializer lists

any a[] = { vs... };

Base specifiers

template <typename... Ts>
struct C : Ts... {};
template <typename... Ts>
struct D : Box<Ts>... { /**/ };

Member initializer lists

// Inside struct D
template <typename... Us>
D(Us... vs) : Box<Ts>(vs)... {}

Tempate argument lists

std::map<Ts...> m;

Will only compile if there is a possible match for the arguments.

Capture lists

template <class... Ts> void fun(Ts... vs) {
    auto g = [&vs...] { return gun(vs...); }
    g();
}

Attribute lists

struct [[ Ts... ]] IAmFromTheFuture {};

It is in the specification, but there is no attribute that can be expressed as a type, yet.

참고URL : https://stackoverflow.com/questions/17652412/what-are-the-rules-for-the-token-in-the-context-of-variadic-templates

반응형