tags:

views:

79

answers:

4

I have a class like this:

template<class T> class A : public T {

// this is done to wrap the base class version of a virtual function
virtual void F(int i) {  
  if(i < 0) T::F(-i);
  else T::F(i);
}

//...

that needs to be constructible for any set of args the base class can be constructed with:

template <typename T1> A(T1 t1) : T(t1) {} 
template <typename T1, typename T2> A(T1 t1, T2 t2) : T(t1, t2) {} 
// ho, hum, copy, paste, yuck.
// ....

All's good but for the default constructor:

template <> A() : T() {}

doesn't compile

A() : T() {} 

fails if T has no default constructor even if A() isn't called.

}

Is there a way to make A() a template without any args?

A: 

If T doesn't have a default constructor, then you don't really have any options. A() : T() { } is an obvious error in this case. Give a broader view of the situation you're in, maybe there's a better way / less convoluted way of doing this entirely.

tenfour
Yes it would be an error. However it wouldn't be if I could some how force that constructor to be a template. That would work because template are lazy; they don't do semantic checking unless you call them, so even though `T()` would fail, it isn't an error as long as I don't call `A<T>()`.
BCS
yea I see what you mean; what about `template<int throwaway = 0> A() : T() { }`
tenfour
to quote clang: `a template parameter of a function template cannot have a default argument in C++98`
BCS
+1  A: 

Might want to give a look at variadic templates if you have access to C++0x to avoid all that boilerplate (below) and scale generically to any number of parameters.

template <typename T1> A(T1 t1) : T(t1) {} 
template <typename T1, typename T2> A(T1 t1, T2 t2) : T(t1, t2) {} 
...

http://www2.research.att.com/~bs/C++0xFAQ.html#variadic-templates

David
This is what I would have used if I could: http://digitalmars.com/d/2.0/template.html#TemplateTupleParameter C++0x is next on my list. This is what I'm stuck with.
BCS
C++0x has a generic tuple container available in the STL (it's built using variadic templates).
David
tuple container? How would that be needed?
BCS
A: 

To sum up, you can't compile T() if T does not have default constructor.

stefanB
+2  A: 

fails if T has no default constructor even if A() isn't called.

class X
{
public:
    X(int) {}
};

template <class T>
class A: public T
{
public:
    A(): T() {}
    template <class U>
    A(const U& u): T(u) {}
};

int main()
{
    A<X> a(1);
    //A<X> b;
}

This appears to compile fine with several compilers. Isn't it the intention of the class templates that unused methods don't cause errors with a particular template parameter, unless actually used?

Perhaps the default constructor for A is being invoked somewhere after all?


The standard has this example to illustrate how the class template and member functions are instantiated. Note that the instantiation of the class and the members are separate:

-3- [Example:

template<class T> class Z {
public:
    void f();
    void g();
};

void h()
{
    Z<int> a;               //  instantiation of class  Z<int>  required
    Z<char>* p;             //  instantiation of class  Z<char>  not
                //  required
    Z<double>* q;           //  instantiation of class  Z<double>
                //  not required

    a.f();                  //  instantiation of  Z<int>::f()  required
    p->g();                 //  instantiation of class  Z<char>  required, and
                //  instantiation of  Z<char>::g()  required
}

Nothing in this example requires class Z, Z::g(), or Z::f() to be implicitly instantiated. ]

This implies, as far as I can see, that not only template methods in a class template are "lazily" instantiated, but so are regular members too.

UncleBens
Bazaar, I can get your results, now... And that lead to the next question of how do you force the instantiation of methods, but that's a different question.
BCS