Могут ли шаблоны C++ проверять, была ли функция перегружена для данного типа?

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

template<typename T>
bool tobool(const T&){ throw Exception("Can't cast to bool");};
template<> bool tobool<bool>(const bool &value){ return value;}

Я знаю, что вы можете проверить существование функции, как в здесь.

Есть ли шанс, как проверить, был ли tobool специализирован?

Представьте, что я хочу сгенерировать isbool(), который возвращает true, если tobool() был специализированным, и возвращает false, если нет.


person Arkaitz Jimenez    schedule 28.11.2010    source источник
comment
Я правильно понимаю? : Вам нужна метафункция, которая для каждого типа T показывает, был ли tobool специализирован для T?   -  person Armen Tsirunyan    schedule 28.11.2010
comment
Да, мне нужно знать, использует ли T универсальный или специализированный инструмент.   -  person Arkaitz Jimenez    schedule 28.11.2010
comment
Итак, во время компиляции вы можете проверить его существование и что делать с результатом?   -  person Martin York    schedule 28.11.2010


Ответы (2)


В качестве обходного пути (несколько уродливого и хрупкого) вы можете потребовать специализации структуры, а не функции, и включить константу класса, чтобы указать, была ли специализирована структура:

template <typename T> 
struct ToBool {
   static bool tobool(const T&);
   static const bool specialized = false;
};

Другой вариант — определить только tobool в специализациях. Таким образом, ToBool<Foo>::tobool(f) не будет компилироваться ни для каких классов Foo, для которых ToBool не предназначен.

В качестве альтернативы tobool вы можете использовать операторы явного преобразования, если у вас есть контроль над преобразуемыми классами.

class Foo {
public:
    operator bool();
    ...
};
...
    Foo f;
    if (f) ...

Если тип не имеет логического преобразования (ну, преобразования в числовой или указательный тип, оба из которых имеют стандартное преобразование в логическое), программа не скомпилируется. Вуаля, проверка времени компиляции на конверсию.

Если вы не хотите неявного преобразования в bool, вы можете определить оператор! и используйте двойной удар для явного преобразования (хотя это не так читабельно):

class Foo {
public:
    bool operator!();
    ...
};

...
    Foo f;
    if (!!f) ...
person outis    schedule 29.11.2010

Ответ на ваш конкретный вопрос таков: нет, вы не можете проверить, использует ли T основной или специализированный шаблон. Вопрос @ Мартина Йорка очень хороший: с какой стати вы хотите это проверить? :)

person Armen Tsirunyan    schedule 28.11.2010
comment
Потому что будет шаблон класса ‹T› с методом isbool(), который должен возвращать true, если tobool‹T› был специализированным, и false, если это не так. - person Arkaitz Jimenez; 28.11.2010