views:

59

answers:

3

Is it possible to have a templated class and also templating the constructor with some other type?

something like this:

template<typename T1>
class Foo{
    template<typename T2>
    Foo(T1 aBar, T2 dummyArgument){
        bar = aBar;
        bytesOfT2 = sizeof(T2);
    };

    int bytesOfT2;
    T1 bar;
};

is this possible? and if so, how would I call such a constructor? Do I need to consider something in regards of header and cpp files?

thanks!

//edit: my particular example is actually even a little bit more complicated. i have

template <typename U1, U2>
class Foo{
    U1 var1;
    U2 var2;
};

template <typename T1>
class Bar{
    template<typename T2, typename T3>
    Bar(Foo<T2,T3> aFoo, T1 aVal){
        val=aVal;
        bytesOfT2=sizeof(T2);
        bytesOfT3=sizeOf(T3);
    };

int bytesOfT2;
int bytesOfT3;
T1 val;
};

does it mean i can here call the constructor just with any variable of type Foo and it should automatically select the proper Constructor acording to the particular version of Foo (for example if the variable i pass is of type Foo should it automatically set T2 to bool and T3 to float)?

+8  A: 

Yes, a class template can have a constructor template. You call it as you would call any other constructor:

Foo<int> my_foo(42, 0.0);

This invokes the constructor template with T1 = int (because T1 is a class template parameter and the class template argument is int) and T2 = double (because T2 is a function template argument and is deduced from the argument 0.0).

All of the template arguments have to be able to be deduced from the function arguments, otherwise the constructor template cannot be called. There is no way to explicitly specify the template arguments for a constructor template.

James McNellis
ah! so I can actually pass an arbitrary variable as the second argument and the compiler will automatically generate the proper version of the constructor for me? i don't even have to mention the type within <> brackets somehow?
Mat
@Mat: Yes. Argument deduction takes place for constructor templates just as it does for other function templates.
James McNellis
what about my extended example (see above) will it select the proper 'sub types' if i provide a typed variable Foo as argument?
Mat
got it to work! =) thanks!
Mat
A: 

You can also use more than one template type:

template<typename T1, typename T2>
class Foo{
public:
    Foo(T1 aBar, T2 dummyArgument){
        bar = aBar;
        bytesOfT2 = sizeof(T2);
    }

private:
    int bytesOfT2;
    T1 bar;
};
Donotalo
I do not want this, I only want the constructor to be of another variable type
Mat
@Mat: i didn't get that while replying. :(
Donotalo
+1  A: 

Yes, it's possible. As for calling the constructor, you just supply one argument of type T1 and a second argument of type T2. That's it (unless one gets into a terminology discussion about "calling").

By the way, instead of first default-initializing bar and then assigning to it, you should just initialize it directly, like

template< class T2 >
Foo( T1 const& aBar, T2 const& dummyArgument )
    : bar( aBar )
    , bytesOfT2( sizeof( T2 ) )
{}

Look up constructors and initializers in your C++ textbook.

Cheers & hth.,

Alf P. Steinbach
ah - i didn't know that i can use expressions in initialization lists - thanks!
Mat