Проверка типа шаблонных параметров класса

0

Я пытаюсь добиться проверки типов параметров класса шаблонов, запретив неявные преобразования типа, такие как string-> bool, тем самым бросая ошибку компиляции. Конкретный сценарий является простым:

#include <iostream>
#include <string>
using namespace std;

template <class T>
class myPair {
T a, b;
public:
  myPair(T first, T second ) {
  a = first;
  b = second;
  }
  void test();
};

typedef myPair<bool> boolParm;

template<class T>
void myPair<T>::test() {
  if(a == true) {
  cout << "a is true" << endl;
  } else {
  cout << "a is false" << endl;   
  }
  if(b == true) {
  cout << "b is true" << endl;
  } else {
  cout << "b is false" << endl;
  }
}

int main() {
  boolParm myObj(false, "false");
  myObj.test();
  return 0;
}

Вывод вышеупомянутого сценария нежелателен, так как пользователь может непреднамеренно передать два разных типа: bool и string и получить первый как false (правильный, поскольку он передан как bool), но второй будет true (неверно, поскольку неявное преобразование типа из строки для bool). Я хочу ограничить код пользователя в main(), чтобы бросать ошибки компиляции и запрещать параметры string/int для передачи в конструкторе. Это должно позволить только bool. Я попытался использовать перегруженный конструктор myPair (сначала bool, строка second), но он не совпадал, так как я предполагаю, что неявное преобразование типа из string-> bool происходит до вызова конструктора. Есть ли какое-либо решение, использующее специализированные шаблоны в этом сценарии? Любая помощь высоко оценена Спасибо

Теги:
templates
typechecking

2 ответа

1

Один из способов - добавить шаблонную фабричную функцию для создания myPair.

template <typename T>
myPair<T> makeParam(T a, T b) {
    return myPair<T>(a, b);
}

Это не скомпилируется с неопределенным параметром шаблона T, если типы не совпадают. Вы можете расширить это с помощью специализированных шаблонов, явно запрещающих определенные типы для T. Ваша основная функция будет выглядеть примерно так:

int main() {
    boolParm myObj = makeParam(false, "false");
    myObj.test();
    return 0;
}

Альтернативно изменить конструктор:

template <typename U, typename V>
myPair(U a, V b);

И специализироваться по мере необходимости

Пример такой специализации:

template <class T>
class myPair {
    T a, b;
public:
    template <typename U, typename V> // generic version
    myPair(U first, V second)
    {
        // intentionally fail to compile
        static_assert(false, "don't support generic types");
    }

    template <> // template specialization
    myPair(T first, T second)
    {
        // explicitly require exactly type T
        a = first;
        b = second;
    }
};
  • 0
    Ах, потому что здесь происходит сбой разрешения шаблона вместо преобразования параметров! гениальное!
  • 0
    Спасибо за комментарии ... Моя проблема в том, что часть main () - это код пользователя, и я не могу попросить пользователей изменить свой код или поддержать уже написанный код пользователя в вышеуказанном формате. Я могу вносить изменения только в базовый класс, т.е. myPair для достижения этой функциональности.
Показать ещё 4 комментария
0

На самом деле это странное поведение на первый взгляд; но, насколько я могу судить, вы не можете запрещать это, но не для примитивных типов, таких как bool.

Неявное преобразование параметров происходит до того, как вы получите ответ на него, и кажется, что существует неявное преобразование примитивного типа из char const * в bool.

См. Также, например, этот другой вопрос: почему строка с кавычками соответствует сигнатуре метода bool перед строкой std :: string?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню