Как проверить, является ли переменная строкового типа в шаблоне класса? - PullRequest
3 голосов
/ 07 января 2020

Я написал следующий конструктор по умолчанию для шаблонного класса, который подписывает все значения здесь на 0. Единственная идея, которую я имею, состоит в том, чтобы проверить, является ли typename T строковым типом, а затем действовать с ним как со строкой.

vec(const size_t size_ = 0): _size(size_), values(_size? new T[_size]:0){
        for(size_t i = 0; i < _size; i++)
            values[i] = 0;
    }

В main я использую это следующим образом:

vec<int> t1; // default constructor works perfectly
vec<string> s2; // ambiguous overload here (signing string to int)

Но я получаю следующую ошибку:

ошибка: неоднозначная перегрузка для ' operator = '(типы операндов:' std :: __cxx11 :: basic_string 'и' int ')

EDIT: Заголовок класса выглядит следующим образом:

...
template<typename T>class vec{
    private:
    size_t _size;
    T * values;
    public:
    vec(const size_t size_ = 0): _size(size_), values(_size? new T[_size]:0){
        for(size_t i = 0; i < _size; i++)
            values[i] = 0;
    }

    ...

1 Ответ

9 голосов
/ 08 января 2020

Вам не нужно знать тип, вам просто нужно использовать лучший инициализатор. Вместо 0 используйте T{} или {} вместо

vec(const size_t size_ = 0): _size(size_), values(_size? new T[_size]:0){
    for(size_t i = 0; i < _size; i++)
        values[i] = T{}; // or values[i] = {};
}

, и теперь вы получите значение, инициализированное T для любого типа T.

Вы можете сделать код еще короче и просто использовать

vec(const size_t size_ = 0): _size(size_), values(_size? new T[_size]{} : 0) {}

и T[_size]{} будет инициализировать весь массив для вас.


Также, пока 0 - это подходящее значение нулевого указателя. Вместо него следует использовать nullptr. Это более точно передает, что вы запрашиваете нулевой указатель, и также может спасти вас, если по какой-то причине ваш тип не станет указателем, поскольку это вызовет ошибку компилятора.

...