Is it possible to create a template function that takes a variable number of arguments, for example, in this Vector< T, C >
class constructor:
template < typename T, uint C >
Vector< T, C >::Vector( T, ... )
{
va_list arg_list;
va_start( arg_list, C );
for( uint i = 0; i < C; i++ ) {
m_data[ i ] = va_arg( arg_list, T );
}
va_end( arg_list );
}
This almost works, but if someone calls Vector< double, 3 >( 1, 1, 1 )
, only the first argument has the correct value. I suspect that the first parameter is correct because it is cast to a double
during the function call, and that the others are interpreted as int
s and then the bits are stuffed into a double
. Calling Vector< double, 3 >( 1.0, 1.0, 1.0 )
gives the desired results. Is there a preferred way to do something like this?
Can there be more than one argument to templates? Yes, like normal parameters, we can pass more than one data type as arguments to templates.
// va_list is a type to hold information about. // variable arguments. va_list ap; // va_start must be called before accessing.
" typename " is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.
A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument. A non-type parameter can be any of the following types: An integral type. An enumeration type. A pointer or reference to a class object.
Alas, right now there's no good way to do this. Most of the Boost packages that need to do something similar use macro tricks to define things like this:
template < typename T >
Vector< T >::Vector( T )
{ ... }
template < typename T, uint C >
Vector< T, C >::Vector( T t, C c1 )
{ ... }
template < typename T, uint C >
Vector< T, C >::Vector( T t, C c1, C c2 )
{ ... }
template < typename T, uint C >
Vector< T, C >::Vector( T t, C c1, C c2, C c3 )
{ ... }
The macros generate some set number (typically around 10) versions, and provide a mechanism to change the max number of parameters before expanding the construction.
Basically, its a real pain which is why C++0x is introducing variable-length template arguments and delegation methods that will let you do this cleanly (and safely). In the meantime you can either do it with macros, or try a C++ compiler that has support for (some of) these new experimental features. GCC is a good one for this.
Be warned though that since C++0x isn't actually out yet, things can still change and your code may not be in sync with the final version of the standard. Plus, even after the standard comes out, there'll be 5 years or so during which many compilers will only partially support the standard, so your code won't be very portable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With