'Is it possible to check if some type doesn't exist in a parameter pack
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) {
...
}
Solution 1:[1]
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) {
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Caleth |
