如果我有变体
Value
:
using Value = std::variant<bool, float>;
那么
std::holds_alternative()
应该可以用这些类型来调用,但不能用其他类型来调用:
Value v;
if (std::holds_alternative<bool>(v))... // compile ok
if (std::holds_alternative<float>(v))... // compile ok
if (std::holds_alternative<int>(v))... // compile error
给定类型 T,我如何检查
std::holds_alternative<T>(const Value&)
是否可调用?
我想做这样的事情
template<class T>
void check() {
if (std::is_invocable_v<decltype(std::holds_alternative<bool>), const Value&>) {
std::cout << "callable";
} else {
std::cout << "not callable";
}
}
但这不会编译,因为我认为它实例化了
std::holds_alternative<bool>
而不考虑 Value
部分。
这里正确的语法是什么?谢谢
遗憾的是,
std::holds_alternative
不适合 SFINE,因此没有好方法直接用 check
编写 std::holds_alternative
函数。相反,您可以根据 std::holds_alternative
的基本要求来实现它,即给定类型在变体的类型列表中只出现一次:
template <typename T, typename... Ts>
constexpr std::size_t count_in_pack()
{
std::array<bool, sizeof...(Ts)> a = { std::is_same_v<T, Ts>... };
return std::count(a.begin(), a.end(), true);
}
template <typename... Ts>
void check(const std::variant<Ts...>&)
{
if (count_in_pack<bool, Ts...>() == 1) {
std::cout << "callable\n";
} else {
std::cout << "not callable\n";
}
};