Как преодолеть ограничение GCC, которое не могло преобразовать аргумент шаблона «0» в «Foo *»?

Предположим, у меня есть такой код:

template<class T, T initial_t> class Bar {
  // something
}

А затем попробуйте использовать его следующим образом:

Bar<Foo*, NULL> foo_and_bar_whatever_it_means_;

GCC выручает с ошибкой (в строке выше):

не удалось преобразовать аргумент шаблона «0» в «Foo*»

Я нашел эту тему: http://gcc.gnu.org/ml/gcc-help/2007-11/msg00066.html, но в этом случае я должен использовать NULL (хорошо, возможно, я мог бы провести рефакторинг, но это было бы непросто; есть предложения?). Я попытался решить проблему, создав переменную со значением NULL, но GCC по-прежнему жалуется, что я передаю переменную, а не адрес переменной в качестве аргумента шаблона. И ссылка на переменную, инициализированную ctor по умолчанию, не будет такой же, как NULL.


person Paweł Hajdan    schedule 09.11.2008    source источник


Ответы (5)


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

person Dan Olson    schedule 09.11.2008

Чтобы принять Bar<Foo, NULL>, вам нужно

template <typename T, int dummy> class Bar; /* Declared but not defined */
template <typename T> class Bar <T,NULL> { /* Specialization */ };

так как typeof(NULL)==int.

person MSalters    schedule 10.11.2008

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

person Nicola Bonelli    schedule 09.11.2008

Ты пытался:

Bar<Foo*, (Foo*)NULL> foo_and_bar_whatever_it_means_;

?

или переинтерпретировать_cast(0)?

person Assaf Lavie    schedule 09.11.2008

@Dan Olson: кажется, есть довольно простой обходной путь.

Создайте родительский класс только с одним параметром шаблона. Добавьте виртуальную функцию, возвращающую T. Для базового класса она должна быть жестко закодирована как NULL. Для производного класса он вернет второй параметр шаблона.

person Paweł Hajdan    schedule 09.11.2008