是否可以检查参数包中是否不存在某种类型

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

我正在做一个 C++14 项目,我刚刚写了一个带有参数包的函数。

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

args只能包含intstd::string,不能是其他类型。

有什么办法可以在编译时进行检查吗?也许如下所示?

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

这在 C++17 中的折叠和 C++20 中的概念中变得更好,但您可以针对 intstd::string.

测试每个元素

递归的第一端是主模板。如果没有专业匹配,我们就是假的。

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

递归的另一端是空包,没错

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

如果我们找到 intstd::string 作为第一个元素,递归剩余的元素

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...> {}

您可能还想去掉限定符。

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...> {}

如此使用

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