You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何使用std::void_t与SFINAE实现的自定义can_visit类型特质编译失败

问题根因

你遇到的核心问题是 std::visit本身不是SFINAE友好的:
C++标准明确规定,当传入的访问器不能覆盖std::variant的所有可选类型时,std::visit的实例化会直接触发硬编译错误,而非返回可被SFINAE捕获的替换失败。这和你参考的can_add逻辑完全不同:普通运算符重载的不匹配属于SFINAE可捕获的替换失败,不会打断编译流程。

正确实现方案

我们可以手动遍历std::variant的所有备选类型,逐个检查访问器是否能调用每个类型,只有所有类型都能被调用时才返回true,实现如下:

#include <variant>
#include <type_traits>
#include <iostream>

// 递归遍历variant类型的辅助实现
template <class TVisitor, class TVariant, size_t Idx = 0>
struct can_visit_impl {
    static constexpr bool value = 
        // 检查当前索引对应类型是否可被访问器调用
        std::is_invocable_v<TVisitor&, std::variant_alternative_t<Idx, TVariant> const&>
        // 递归检查下一个索引的类型
        && can_visit_impl<TVisitor, TVariant, Idx + 1>::value;
};

// 递归终止条件:所有类型遍历完成
template <class TVisitor, class TVariant>
struct can_visit_impl<TVisitor, TVariant, std::variant_size_v<TVariant>> {
    static constexpr bool value = true;
};

// 对外暴露的类型特质
template <class TVisitor, class TVariant, class = void>
struct can_visit : std::false_type {};

template <class TVisitor, class TVariant>
struct can_visit<TVisitor, TVariant, std::enable_if_t<can_visit_impl<TVisitor, TVariant>::value>>
    : std::true_type {};

// 便捷变量模板
template <class TVisitor, class TVariant>
constexpr bool can_visit_v = can_visit<TVisitor, TVariant>::value;
测试验证

用你提供的测试用例可得到预期结果:

struct A{};
struct B{};
struct C{};

using ABC = std::variant<A,B,C>;
using AB = std::variant<A,B>;

struct ABCVis {
    void operator()(A const & a){};
    void operator()(B const & a){};
    void operator()(C const & a){};
};
struct ABVis {
    void operator()(A const & a){};
    void operator()(B const & a){};
};

int main(){
    std::cout << can_visit_v<ABVis, ABC> << std::endl; // 输出0,符合预期
    std::cout << can_visit_v<ABCVis, ABC> << std::endl; // 输出1
    std::cout << can_visit_v<ABVis, AB> << std::endl; // 输出1
}

如果你实际调用std::visit时会传非const的variant、右值访问器等参数,只需调整std::is_invocable_v里的参数值类别和实际调用逻辑对齐即可。


内容的提问来源于stack exchange,提问作者bradgonesurfing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 05:24:01