Наследование от нешаблонного класса с шаблонным конструктором — как разрешить неоднозначность?

Допустим, у нас есть класс MyParent:

class MyParent
{
public:
  template<namespace T>
  MyParent()
  {
    T* Something;
  }
};

И производный класс, который использует этот конструктор:

class MyDerived : public MyParent
{
public:
  MyDerived()
  : MyParent<int>()
  {
  }
};

Затем я получаю ошибку компиляции, потому что есть двусмысленность. Компилятор считает, что int является аргументом шаблона для класса, а не конструктора.

Как указать, что я хочу, чтобы int был аргументом конструктора?


person Geeho    schedule 08.01.2009    source источник
comment
Нужно ли скрывать T в реализации конструктора? Разве не должен быть аргумент конструктору типа T?   -  person Nathan Kitchen    schedule 08.01.2009
comment
НЕ НУЖНО быть. Но было бы проще, если бы они были.   -  person Martin York    schedule 08.01.2009
comment
Вы имеете в виду этот шаблон‹ typename T? (Никогда не видел конструкции ‹namespace T›...)   -  person xtofl    schedule 08.01.2009


Ответы (2)


Это невозможно. В стандартном разделе 14.8.1 Явный аргумент шаблона отмечается:

[Примечание: поскольку список явных аргументов шаблона следует за именем шаблона функции, а шаблоны функций-членов преобразования и шаблоны функций-членов конструктора вызываются без использования имени функции, невозможно предоставить явный список аргументов шаблона для этих шаблонов функций. ]

Как отмечено в комментариях, вам нужно, чтобы конструктор принимал параметр типа T (или const T &), а затем MyDerived вызывал MyParent::MyParent с параметром типа int.

person Greg Rogers    schedule 08.01.2009

Обратите внимание, что ваш вопрос не относится к наследованию. Учитывая ваш пример кода, вы вообще не можете создать экземпляр MyParent либо потому, что он не принимает список аргументов шаблона, либо потому, что у него нет конструктора по умолчанию.

Чтобы создать экземпляр MyParent с помощью шаблона конструктора, вам нужно предоставить компилятору какой-то способ узнать аргумент шаблона, и вы не можете сделать это с конструктором без аргументов. Вам нужно дать конструктору MyParent параметр. Вот пример, основанный на коде Альфа П. Штайнбаха:

template <typename T>
struct UseMethodsOf {};

class MyParent
{
public:
  template <typename T>
  MyParent(UseMethodsOf<T>)
  {
    T* Something;
  }
};

class MyDerived: public MyParent
{
public:
  MyDerived()
  : MyParent(UseMethodsOf<int>())
  {
  }
};
person Rob Kennedy    schedule 08.01.2009
comment
Теперь вы тоже сделаете его настолько полным, насколько это возможно. Один дает мне истинный ответ, другой дает мне обходной путь. Спасибо вам обоим! - person Geeho; 09.01.2009