Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Template Class Constructor with Variable Arguments

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 ints 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?

like image 306
david Avatar asked Apr 13 '10 05:04

david


People also ask

Can there be more than one arguments to templates?

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.

What is Va_list in C?

// va_list is a type to hold information about. // variable arguments. va_list ap; // va_start must be called before accessing.

What is Typename in C++ template?

" 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.

What is a non-type template parameter?

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.


1 Answers

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.

like image 80
swestrup Avatar answered Sep 19 '22 21:09

swestrup