Home > Blockchain >  Is it possible to check if some type doesn't exist in a parameter pack
Is it possible to check if some type doesn't exist in a parameter pack

Time:05-10

I'm working on a C 14 project and I just wrote a function with parameter pack.

template <typename... Args>
void func(Args&&... args) {
    ...
}

The args should contain only int or std::string, it can't be any other types.

Is there any way to do the check at compile time? Maybe something as below?

template <typename... Args, std::enable_if_t<???* = nullptr>
void func(Args&&... args) {
    ...
}

CodePudding user response:

This gets better with folds in C 17 and concepts in C 20, but you can test each element against int and std::string.

The first end of the recursion is the primary template. If no specialisation matches, we are false.

template <typename... Ts>
struct all_int_or_string : std::false_type {};

The other end of recursion is the empty pack, which is true.

template <>
all_int_or_string<> : std::true_type {};

If we find int or std::string as the first element, recurse the remaining elements

template <typename... Ts>
struct all_int_or_string<int, Ts...> : all_int_or_string<Ts...> {}

template <typename... Ts>
struct all_int_or_string<std::string, Ts...> : all_int_or_string<Ts...> {}

You probably also want to strip off qualifiers.

template <typename T, typename... Ts>
struct all_int_or_string<const T, Ts...> : all_int_or_string<T, Ts...> {}

template <typename T, typename... Ts>
struct all_int_or_string<volatile T, Ts...> : all_int_or_string<T, Ts...> {}

template <typename T, typename... Ts>
struct all_int_or_string<T &, Ts...> : all_int_or_string<T, Ts...> {}

template <typename T, typename... Ts>
struct all_int_or_string<T &&, Ts...> : all_int_or_string<T, Ts...> {}

Used thusly

template <typename... Args, std::enable_if_t<all_int_or_string<Args...>::value>* = nullptr>
void func(Args&&... args) {
}
  • Related