가변 템플릿의 맥락에서“…”토큰에 대한 규칙은 무엇입니까?
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.
'Programing' 카테고리의 다른 글
IP 주소 ':: 1'은 무엇입니까? (0) | 2020.08.25 |
---|---|
matplotlib 플롯의 왼쪽 상단 모서리에 텍스트 넣기 (0) | 2020.08.25 |
Android에서 터치 이벤트를 시뮬레이션하는 방법은 무엇입니까? (0) | 2020.08.25 |
Visual Studio가 어딘가에서 프로젝트에 대한 잘못된 경로를 검색합니다. (0) | 2020.08.25 |
connect / expressjs에서 "서명 된"쿠키는 무엇입니까? (0) | 2020.08.25 |