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

template <>
class Vec<double> : public VecBase<double>
{
    //  == METHODS ==
    public:
        //  -- Constructors & Destructors --
        explicit Vec(const unsigned long long t_size);
        virtual ~Vec();

        //  -- Operators --
        friend Vec<double> operator+(const Vec<double>&, const double);

        //  -- Methods --
        double sum();

... etc.

Я частично специализировал шаблон класса, чтобы разрешить перегрузку математических операторов для двойной специализации. Теперь я хотел бы расширить эту специализацию и до int, но вместо того, чтобы копировать специализацию, заменяя double на int, есть ли способ добавить ее в список специализации?

То есть есть ли способ учесть:

template<>
class Vec<double (or) int>

Ура !

3
user7119460 24 Апр 2017 в 02:04

2 ответа

Лучший ответ

Я полагаю, вы можете использовать логическое значение по умолчанию, как в foo struct в следующем примере

#include <iostream>

template <typename>
struct isSpecialType
 { static constexpr bool value { false }; };

template <>
struct isSpecialType<int>
 { static constexpr bool value { true }; };

template <>
struct isSpecialType<double>
 { static constexpr bool value { true }; };

template <typename T, bool = isSpecialType<T>::value>
struct foo;

template <typename T>
struct foo<T, true>
 { static constexpr bool value { true }; };

template <typename T>
struct foo<T, false>
 { static constexpr bool value { false }; };

int main()
 {
   std::cout << "- void value:   " << foo<void>::value << std::endl;
   std::cout << "- bool value:   " << foo<bool>::value << std::endl;
   std::cout << "- int value:    " << foo<int>::value << std::endl;
   std::cout << "- double value: " << foo<double>::value << std::endl;
 }

Идея состоит в том, чтобы определить тип черт типа (isSpecialType) для выбора выбранных типов (int и double, в вашем примере) с логическим значением, равным false в общая реализация и true в специализациях.

template <typename>
struct isSpecialType
 { static constexpr bool value { false }; };

template <>
struct isSpecialType<int>
 { static constexpr bool value { true }; };

template <>
struct isSpecialType<double>
 { static constexpr bool value { true }; };

Затем вы должны объявить структуру foo (class Vec, в вашем вопросе) с дополнительным значением шаблона bool со значением по умолчанию isSpecialType<T>::value

template <typename T, bool = isSpecialType<T>::value>
struct foo;

Наконец, вы должны реализовать две частично специализированные версии foo: первая с логическим значением true

template <typename T>
struct foo<T, true>
 { static constexpr bool value { true }; };

Соответствующий специализированной версии вашего Vec; один с логическим значением false

template <typename T>
struct foo<T, false>
 { static constexpr bool value { false }; }; 

В соответствии с общей версией вашего Vec.

Еще один момент: мой пример - C ++ 11 или более новый код; если вы хотите версию C ++ 98, вам нужно только определить значения bool как const (вместо constexpr) и инициализировать их в стиле C ++ 98; Я имею в виду

 static bool const bool value = true;

Вместо

 static constexpr bool value { true };
1
max66 24 Апр 2017 в 00:16

Конечно, есть, но вы можете найти это уже в http : //en.cppreference.com/w/cpp/numeric/valarray

Взгляните на std :: enable_if и std :: is_integral и std :: is_floating_point. (скопировано с cplusplus.com)

// enable_if example: two ways of using enable_if
#include <iostream>
#include <type_traits>

// 1. the return type (bool) is only valid if T is an integral type:
template <class T>
typename std::enable_if<std::is_integral<T>::value,bool>::type
  is_odd (T i) {return bool(i%2);}

// 2. the second template argument is only valid if T is an integral type:
template < class T,
           class = typename std::enable_if<std::is_integral<T>::value>::type>
bool is_even (T i) {return !bool(i%2);}

int main() {

  short int i = 1;    // code does not compile if type of i is not integral

  std::cout << std::boolalpha;
  std::cout << "i is odd: " << is_odd(i) << std::endl;
  std::cout << "i is even: " << is_even(i) << std::endl;

  return 0;
}
1
Captain Giraffe 24 Апр 2017 в 01:17