What are the 6 points in the template options packages?

Considering this question, I ended up on the cpp help site where I noticed a strange and new syntax for me:

template<class Ret, class... Args> struct is_function<Ret(Args......)volatile &&> : std::true_type {}; 

Yes, 6 points! Initially, I thought it was a typo, but after checking libstdC ++ source it was again, for example, on line 444:

 template<typename _Res, typename... _ArgTypes> struct is_function<_Res(_ArgTypes......) volatile &&> : public true_type { }; 

Is this a valid syntax? Point point, used for packing and unpacking parameter packets? What do 6 points do?

+12
c ++ c ++ 11 c ++ 14 variadic-templates partial-specialization
Dec 21 '14 at 23:06
source share
2 answers

In this case, they are intended for different purposes. The first is for expanding the package of parameters, and the second is for lists of variable arguments. This particular declaration should handle functions that take some regular parameters plus a list of variable arguments.

The difference between runtime and variability in compilation time. A special function that takes a variable number of arguments at run time. This is the only function that can handle a variable number of arguments from the caller:

 void f(int x,...) // equivalent to void f(int x ...) { // Do some run-time logic here to determine what to // do with parameters after x. } 

This is different from the notion that we want to have a template that uses many functions with various parameters that are known at compile time. For example, we could define a function template that takes a pointer to a function and allows you to change the number and types of arguments:

 template <typename... Args> void g(void (*function_ptr)(Args...)) { // We can do logic here to call function_ptr with the proper // number of arguments. } 

Given these features:

 void f1(int); void f2(int,float); 

You can call g with any of them:

 g(f1); // fine g(f2); // also fine 

However

 g(f); // error 

The compiler did not know what to use for the Args parameter package in g .

+7
Dec 21 '14 at 23:10
source share

Why libstdc++ use ... ... in the implementation of is_function ? If we check the cppreference section for std :: is_function , it gives an example implementation and says for the first case ... ... :

 // specialization for variadic functions such as std::printf template<class Ret, class... Args> struct is_function<Ret(Args......)> : std::true_type {}; 

so we need a second set ... to match a function variable, such as printf :

  Comma optional as per 8.3.5 [dcl.fct] | v Ret(Args... ...) ^ ^ | | Match a function with a variable number of arguments | and the function is a variadic function 

Note that we have functions such as fprintf that have two arguments before variable members, and we also need to match them. Indeed, if we use this implementation and try to match printf without specialization ... ... then it fails to see it live .

This corner of the language is considered in this C ++ 11 post six points :

I pounced the other day and discovered this cute little weirdness:

 template <typename... Args> void foo(Args......); 

As it turned out, ...... C ++ 11 may be completely valid. This is what happens when backward compatibility mixes with the new heat.

// All are equivalent.

 template <typename... Args> void foo1(Args......); template <typename... Args> void foo2(Args... ...); template <typename... Args> void foo3(Args..., ...); 

I hope the latter shows what is happening here. [...]

Why is it wallill? We can see that , ... is a synonym ... from the standard section of the C ++ 11 8.3.5 project [dcl.fct], which has the following grammar:

 parameter-declaration-clause: parameter-declaration-listopt...opt parameter-declaration-list , ... 

and says:

[...] Where is syntactically correct and where "..." is not part of the abstract-declarator, ", ..." is synonymous with "...". [...]

+54
Nov 03 '15 at 15:12
source share



All Articles