开发者

Argument forwarding for no argument cases

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) {} 
te开发者_开发问答mplate <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?


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.


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


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜