C++只接受模板参数包的一组类型



要将模板参数包限制为特定类型,可以通过以下方式完成:

std::enable_if_t<std::conjunction_v<std::is_same<int32_t, Ts>...>>
send(bool condition, Ts...);

实际上,我会允许int32_t和std::string以及任何顺序。

如何表达?

我有一个使用变体的变通方法,但这对我来说不太好:

using allowed_types = std::variant<int32_t, std::string>;
template<typename... Ts>
std::enable_if_t<std::conjunction_v<std::is_assignable<allowed_types, Ts>...>>
send(bool condition, Ts...);

这并不能编译:

std::enable_if_t<std::conjunction_v<std::is_same<int32_t, Ts> || std::is_same<std::string, Ts>...>> // <- does not compile!
send(bool condition, Ts...);

您在std::bool_constant级别上正确地使用std::conjunction作为&&的替代品,但您应该以相同的方式将||替换为std::disjunction:

std::enable_if_t<std::conjunction_v<std::disjunction<std::is_same<int32_t, Ts>, std::is_same<std::string, Ts>>...>>

或者使用C++17,您可以在bool值的级别上使用折叠表达式:

std::enable_if_t<((std::is_same_v<int32_t, Ts> || std::is_same_v<std::string, Ts>) && ...)>>

(折叠表达式语法需要外括号。(

当然,在C++20的帮助下,这可以做得更好:

template<typename T>
concept Int32OrString = std::same_as<T, int32_t> || std::same_as<T, std::string>;
void send(bool condition, Int32OrString auto...);

甚至

template<typename T, typename... Ts>
concept AnyOf = (std::same_as<T, Ts> || ...);
void send(bool condition, AnyOf<int32_t, std::string> auto...);

相关内容

最新更新