2010-11-28 4 views
2

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

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

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

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

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

+1

Правильно ли я понимаю? : Вам нужен метафунд, который для каждого типа T показывает, был ли tobool специализирован для T? – 2010-11-28 20:33:20

+0

Да, мне нужно знать, использует ли T общий или специализированный тобул. – 2010-11-28 20:34:27

ответ

3

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

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), программа не будет компилироваться. Voila, время компиляции для преобразования.

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

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

... 
    Foo f; 
    if (!!f) ... 
0

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