
Hello, On Apr 16, 2007, at 3:33 PM, Marco wrote:
I gave a glance to the papers about variadic templates and I didn't see examples using a construct such as f(args)... where args is a function parameter pack; so I guess that the following code it's illegal:
The specification of variadic templates is the authority on what can and can't be done with them. The compiler, and the examples in the papers, just help to illustrate some of the capabilities. In this case...
template< typename T > T max( T x ) { return x; }
template< typename T, typename... Args > // where are_same<T, Args...> T max( T x, T y, Args... args ) { return std::max( x, max( y, args... ) ); }
// #1 template< typename T, typename... Args > // where are_same<T, Args...> T max_abs( T x, T y, Args... args ) { // this is the (probably) illegal construct: return max( abs(x), abs(y), abs(args)... ); // I'd like that "abs(args)..." expands to "abs(arg1), ... ,abs (argN)" }
Sure, that's fine.
What's the rationale behind such a design choice ?
It's a great idea, so we did it :)
I admit that a simple workaround exists:
// #2 template< typename T > T max_abs( T x ) { return abs(x); }
template< typename T, typename... Args > // where are_same<T, Args...> T max_abs( T x, T y, Args... args ) { return std::max(abs(x), max_abs(y, args...) ); }
anyway version #1 is more straightforward, and maybe it's possible to make up examples more complex than mine.
The implementations of Bind, Function, and Tuple involve much more complex uses of variadic templates.
Another question: given the following functions:
// #1 template< typename T > void f(T ) {}
// #2 template< typename T, typename... Args > void f(T, Args... ) {}
the function call f(1,2) is it ambiguous ? if it isn't, which is the function called ? #1 because it's more specialized ? (only a guess)
For f(1, 2), only #2 matches. For f(1), both #1 and #2 match, but #1 is more specialized. - Doug