С++ - как проверить, является ли тип класса шаблона недействительным?

Мне нужен способ проверить, является ли тип шаблонного класса недействительным.

Вот моя попытка:

template <typename target_type, typename start_function_type, typename end_function_type> class C_rule {

  public:
    //...
    void setIntoEffect(bool true_or_false) {
          if (true_or_false == true) {
             for (size_t i = 0; i < targets.size(); i++) {
                 if (typeid(start_function_type) != typeid(void)) {
                    start_function_type start_function_return_value = enforceOnTarget(targets.at(i));
                 }

                 else {
                    enforceOnTarget(targets.at(i));
                 }
             }
          }

          else if ((true_or_false == false) && (is_in_effect == true)) {
             for (size_t i = 0; i < targets.size(); i++) {
                 if (typeid(end_function_type) != typeid(void)) {
                    end_function_type end_function_return_value = removeFromTarget(targets.at(i));
                 }

                 else {
                    removeFromTarget(targets.at(i));
                 }
             }
          }
          is_in_effect = true_or_false;
     }

  protected:
    //...
  private:
    //...

};

Однако это генерирует ошибку компилятора, жалующуюся на то, что две переменные «start_function_return_value» и «end_function_return_value» объявляются недействительными при создании объекта C_rule с пустыми «start_function_type» и «end_function_type». Я пытаюсь предотвратить создание переменной для хранения возвращаемого значения из функций «начало» и «конец» для правила, если тип возвращаемого значения этих функций недействителен (поскольку функции недействительности, очевидно, ничего не возвращают). И, как видите, я пытаюсь использовать для этой цели оператор typeid, но, похоже, он не работает. По-видимому, оператор if все еще вводится, когда start_function_type и end_function_type недействительны, и я не знаю, почему. Может быть, typeid не работает с пустотой? Я гуглил вопрос, но не нашел ответа, поэтому и задаю его здесь.

Заранее спасибо.


person Jammanuser    schedule 02.03.2013    source источник
comment
Возможно, это помогает? stackoverflow .com/questions/9625526/   -  person chris    schedule 02.03.2013
comment
Как насчет std::is_void?   -  person Kerrek SB    schedule 02.03.2013
comment
Проблема в том, что у нас нет статического if. Если бы мы это сделали, вы могли бы сделать то, что пытаетесь сделать сейчас, но с std::is_same или std::is_void вместо typeid.   -  person chris    schedule 02.03.2013
comment
Хм..std::is_void давал мне надежду, но после того, как я только что попробовал это в этих операторах if вместо выражений typeid, компилятор выдал мне следующую ошибку:   -  person Jammanuser    schedule 02.03.2013
comment
Этот файл требует поддержки компилятором и библиотекой нового стандарта \ ISO C++, C++0x. В настоящее время эта поддержка является экспериментальной и должна быть включена с параметрами компилятора -std=c++0x или -std=gnu++0x.   -  person Jammanuser    schedule 02.03.2013
comment
@Jammanuser, ответы по моей ссылке все равно должны помочь.   -  person chris    schedule 02.03.2013


Ответы (1)


В C++11 вы можете использовать стандартную черту типа std::is_same<>, чтобы проверить, совпадают ли два типа:

#include <type_traits>

// ...
bool same = std::is_same<T1, T2>::value;

В вашем случае это может быть:

bool same = std::is_same<start_function_type, void>::value;

Однако это не решит вашу проблему, поскольку оператор if не является (static) if: обе ветви оператора if все еще должны быть скомпилированы .

Что вы можете сделать, так это специализировать свой шаблон класса для случаев, когда start_function_type или end_function_type равно void, или выделить часть кода, которая имеет дело с ними, в отдельный специализированный шаблон класса.

person Andy Prowl    schedule 02.03.2013
comment
Хм... моя одна большая проблема в том, что я сейчас использую С++ 98, и я не знаю, как обновить мой компилятор и IDE, чтобы вместо этого использовать С++ 11. Не могли бы вы помочь с этим? Сейчас я использую IDE — Qt Creator, а компилятор — MinGW. - person Jammanuser; 02.03.2013
comment
@Jammanuser: Что ж, если вы будете специализировать свой шаблон, вам не нужен C ++ 11. Просто узнайте о специализации шаблонов. Я опубликую более подробный код, если у меня будет время. - person Andy Prowl; 02.03.2013
comment
@Jammanuser, Этот сайт подходит для дистрибутивов MinGW. Имейте в виду, что GCC 4.8.0 тоже скоро выйдет. Не забудьте использовать -std=c++11. В любом случае, я не вижу, где здесь нужен С++ 11. Как говорится в ответе, вам нужно специализироваться, пока у нас нет static if. - person chris; 02.03.2013
comment
Что ж, у меня возникают проблемы с пониманием концепции специализации моего шаблона класса для случаев, когда start_function_type или end_function_type являются недействительными, когда кажется, что единственный способ проверить, являются ли они недействительными, — это использовать std::is_void или std ::is_same, которые оба используют C++11 (или это C++0x??..). - person Jammanuser; 02.03.2013
comment
Подождите... если вы не имели в виду, указав тип void в самом шаблоне, тем самым заставив тип всегда быть недействительным (если это вообще работает). Но это побеждает всю цель создания шаблонов, не так ли... - person Jammanuser; 02.03.2013
comment
@Jammanuser: Попробуйте немного прочитать о специализации шаблонов классов, и вы поймете, что я имею в виду. Вам не нужно std::is_void. - person Andy Prowl; 02.03.2013
comment
Что ж, я только что это сделал, но похоже, что в статье, которую я читал (на cprogramming.com), говорилось о специализации общего типа шаблона путем добавления ‹T *› после имени класса, что, как сказано, указывает компилятору сопоставлять указатели. любого типа к более общему имени типа. Но я не понимаю, как это могло бы помочь в моем случае, поскольку я хотел, чтобы тип функции запуска и тип функции завершения были буквально любыми, которые хотел пользователь. Специализация типа с помощью указателей заставила бы тип начальной функции и тип конечной функции быть типом указателя, не так ли? Например, я не мог использовать void. - person Jammanuser; 02.03.2013