Переадресация аргументов без аргументов - PullRequest
1 голос
/ 14 сентября 2010

У меня есть такой класс:

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);
}

//...

, который должен быть конструируемым для любого набора аргументов, базовый класс может быть создан с помощью:

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

Все хорошо, но для конструктора по умолчанию:

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

не компилируется

A() : T() {} 

завершается неудачно, если T не имеет конструктора по умолчанию, даже если A () не вызывается.

}

Есть ли способ сделать A() шаблоном без аргументов?

Ответы [ 4 ]

2 голосов
/ 14 сентября 2010

завершается ошибкой, если T не имеет конструктора по умолчанию, даже если A () не вызывается.

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;
}

Похоже, что он хорошо компилируется с несколькими компиляторами.Разве это не намерение шаблонов классов в том, что неиспользуемые методы не вызывают ошибок с определенным параметром шаблона, если они не используются на самом деле?

Возможно, конструктор по умолчанию для A вызывается где-нибудь в конце концов?


Стандарт имеет этот пример, чтобы проиллюстрировать, как создаются шаблон класса и функции-члены.Обратите внимание, что создание экземпляров класса и членов разделено:

-3- [Пример:

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
}

Ничто в этом примере не требует класса Z, Z :: g () илиZ :: f () должен быть создан неявно.]

Насколько я понимаю, это подразумевает, что не только "лениво" создаются экземпляры не только методов шаблона в шаблоне класса, но и обычные члены.

1 голос
/ 14 сентября 2010

Возможно, вам захочется взглянуть на шаблоны с переменными параметрами, если у вас есть доступ к C ++ 0x, чтобы избежать всего этого шаблонного примера (см. Ниже) и в общем случае масштабировать до любого количества параметров.

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

0 голосов
/ 14 сентября 2010

Подводя итог, вы не можете скомпилировать T(), если T не имеет конструктора по умолчанию.

0 голосов
/ 14 сентября 2010

Если T не имеет конструктора по умолчанию, тогда у вас нет никаких вариантов.A() : T() { } является очевидной ошибкой в ​​этом случае.Дайте более широкое представление о ситуации, в которой вы находитесь, возможно, есть лучший способ / менее запутанный способ сделать это полностью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...