Совпадение частично или полностью наберите пакет параметров - PullRequest
0 голосов
/ 03 июля 2018

Я хочу проверить, соответствует ли пакет параметров типа частично или полностью другому пакету параметров.

Пока что я пытаюсь это сделать:

template<typename... Arguments>
struct VariadicArguments
{
    template<typename... AnotherArguments>
    struct IsSame: std::bool_constant<sizeof...(AnotherArguments)==0> {};
};

template<typename Arg, typename... Arguments>
struct VariadicArguments<Arg, Arguments...>
{
    template<typename... Args>
    struct IsSame: std::false_type{};

    template<typename AnotherArg, typename... AnotherArguments>
    struct IsSame<AnotherArg, AnotherArguments...>:
        std::bool_constant<
            std::is_same<Arg, AnotherArg>::value &&
            VariadicArguments<Arguments...>::IsSame<AnotherArguments...>::value> { };

    template<>
    struct IsSame<> : std::true_type{};
};

template<>
struct VariadicArguments<>
{
    template<typename... Args>
    struct IsSame : std::false_type {};

    template<>
    struct IsSame<> : std::true_type {};
};

Я предсказал, что

VariadicArguments<int, float, double>::IsSame<int, float>::value // true because (int, float, double) partially matches (int, float)
VariadicArguments<int, float, double>::IsSame<int, double>::value // false because (int, float, double) doesn't partially matches (int, double) it should be in serial
VariadicArguments<int, float, double>::IsSame<int, float, double>::value // true because they are all same in serial
VariadicArguments<int, float, double>::IsSame<>::value // true because no arguments matches every parameter pack.

Но я получаю некоторые ошибки во время компиляции

1> signal.hpp (25): ошибка C2210: '_Val': расширения пакета нельзя использовать в качестве аргументов для неупакованных пакетов параметры в шаблонах псевдонимов

1> signal.hpp (25): примечание: см. ссылка на создание шаблона класса 'VariadicArguments :: IsSame' компилируется 1> d: \ dell \ source \ repos \ mimg \ mimg-base \ signal.hpp (29): примечание: см. ссылку на создание шаблона класса 'VariadicArguments' компилируется

1> signal.hpp (25): ошибка C3770: 'unknown-type': недопустимый базовый класс

1> signal.hpp (25): предупреждение C4346: 'VariadicArguments :: IsSame': зависимое имя не является введите 1> d: \ dell \ source \ repos \ mimg \ mimg-base \ signal.hpp (25): примечание: префикс «typename» для обозначения типа

1> signal.hpp (25): ошибка C2143: синтаксическая ошибка: отсутствует ',' before '::'

1> signal.hpp (25): ошибка C2039: 'значение': не является членом '' глобального пространства имен ''

1> signal.hpp (25): ошибка C2143: синтаксическая ошибка: отсутствует ',' before '>'

1> signal.hpp (41): ошибка C3769: «VariadicArguments»: вложенный класс не может иметь то же имя, что и немедленно включающий класс

1> signal.hpp (57): ошибка C2953: 'VariadicArguments <> :: VariadicArguments': класс шаблон уже определен

1> signal.hpp (16): примечание: см. декларация о 'VariadicArguments <> :: VariadicArguments'

1> signal.hpp (67): ошибка C3412: 'VariadicArguments <>': не может специализировать шаблон в текущей области

1 Ответ

0 голосов
/ 03 июля 2018

Я предлагаю более простой VariadicArguments (переименован VarArgs, чтобы сделать его короче)

template <typename...>
struct VarArgs;

template <typename A0, typename ... As>
struct VarArgs<A0, As...>
 {
   template <typename ... Bs>
   struct IsSame  : std::integral_constant<bool, sizeof...(Bs)==0>
    { };

   template <typename ... Bs>
   struct IsSame<A0, Bs...> : VarArgs<As...>::template IsSame<Bs...>
    { };
 };

template <>
struct VarArgs<>
 {
   template <typename ... Bs>
   struct IsSame : std::integral_constant<bool, sizeof...(Bs)==0>
    { };
 };

Теперь вы можете написать

int main ()
 {
   using ifd = VarArgs<int, float, double>;

   static_assert(  true == ifd::IsSame<int, float>::value, "1!" );
   static_assert( false == ifd::IsSame<int, double>::value, "2!" );
   static_assert(  true == ifd::IsSame<int, float, double>::value, "3!" );
   static_assert(  true == ifd::IsSame<>::value, "4!" );
 }

Обратите внимание, что при использовании std::integral_constant<bool, BoolValue> вместо std::bool_constant<BoolValue> это решение работает также для C ++ 11 и C ++ 14, а не только для C ++ 17.

...