Как упростить этот код C ++ с шаблоном? - PullRequest
0 голосов
/ 19 марта 2020

Это простой вопрос, как сделать этот класс проще?

template<typename size_type = uint16_t>
class package
{
public:
    template<typename T,typename std::enable_if<std::is_same_v<uint32_t,T>,int>::type = 0>
    package(uint8_t* data,T length) : package(data,(size_type)length)
    {
        std::cout << "uint32_t" << std::endl;
    }
    package(uint8_t* data,size_type length)
    {

    }
}
template<typename T,typename std::enable_if<std::is_same_v<uint32_t,T>,int>::type = 0>

Поскольку этот раздел кода мне не нравится, он выглядит уродливым и слишком длинным.

Ответы [ 3 ]

0 голосов
/ 19 марта 2020

Вы можете довольно легко упростить это, по крайней мере, немного, хотя это не намного короче.

void print(char const *data, uint32_t) { std::cout << data << ", uint32_t\n"; }

template <class T>
void print(char const *data, T length) { std::cout << data << "\n"; }

template <class size_type = uint16_t>
class package
{
public:
    package(char const *data, size_type size) { print(data, size); }
};

На данный момент я изменил его на использование char *, и обе функции выполняют мало печати, поэтому легко протестировать и проверить, как это работает:

int main() {
    package<uint32_t> m("input", 1234);
    package<uint16_t> n("more input", 1234);
}

Результат:

input, uint32_t
more input
0 голосов
/ 19 марта 2020

может быть, вам нужно вот так, используйте функцию шаблона package_print_type, чтобы напечатать тип шаблона, сделайте класс шаблона понятным.


template<typename size_type>
void package_print_type()
{}

template <>
void package_print_type<uint32_t>()
{
    std::cout << "uint32_t" << std::endl;
}

template<typename size_type = uint16_t>
class package
{
public:
    package(uint8_t* data,size_type length)
    {
         package_print_type<size_type>();

    }
};

вы также можете написать функцию перегрузки:

template<typename size_type>
void package_print_type(size_type l)
{}


void package_print_type(uint32_t l)
{
    std::cout << "uint32_t" << std::endl;
}

template<typename size_type = uint16_t>
class package
{
public:
    package(uint8_t* data,size_type length)
    {
         package_print_type(length);

    }
};

Я тестирую его в Compiler Explorer , вы можете увидеть результат.

0 голосов
/ 19 марта 2020

Не уверен, что понимаю, что вы имеете в виду под словом "упростить", но ... как насчет следующего?

template <typename size_type = std::uint16_t>
struct package
 {
   template <typename T,
             std::enable_if_t<std::is_same_v<std::uint32_t, T>
                           || std::is_same_v<size_type, T>, int> = 0>
   package (std::uint8_t *, T)
    {
      if constexpr ( std::is_same_v<std::uint32_t, T> )
         std::cout << "uint32_t" << std::endl;
    }
 };

Я имею в виду ... параметр шаблона, включенный SFINAE, только когда T is std::uint32_t или size_type (это также может быть std::uint32_t).

цель в том случае, когда size_type равен uint32_t, вывести «uint32_t», другие типы не распечатать

Вы можете проверить, является ли T 1015 * внутри тела конструктора. С if constexpr, если вы используете C ++ 17 или C ++ 20.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...