如何将 is_invocable 与变体和 std::holds_alternative 一起使用

问题描述 投票:0回答:1

如果我有变体

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
部分。 这里正确的语法是什么?谢谢

c++ templates variant
1个回答
0
投票

遗憾的是,

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";
    }
};
© www.soinside.com 2019 - 2024. All rights reserved.