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

如何在重载选择后检测被删除函数(排除无可行/歧义重载)

检测重载决议后选中被删除函数的方法

要实现你需要的foo_is_deleted trait,我们可以通过两层SFINAE分别检测是否存在可行重载和选中的重载是否可调用,两者结合即可区分目标场景:

#include <type_traits>
#include <utility>
#include <string>
#include <vector>

// 原函数重载
void foo();
void foo(double) = delete;
void foo(std::string);

void foo(char, int);
void foo(int, char);

// 检测是否存在可行重载(重载决议能选出唯一函数,无论是否被删除)
template <typename... Args, typename = void>
struct has_viable_overload : std::false_type {};

template <typename... Args>
struct has_viable_overload<Args..., std::void_t<decltype(foo(std::declval<Args>()...))>> : std::true_type {};

// 检测选中的重载是否可调用(即未被删除)
template <typename... Args, typename = void>
struct is_callable : std::false_type {};

template <typename... Args>
struct is_callable<Args..., std::void_t<decltype((foo(std::declval<Args>()...)))>> : std::true_type {};

// 最终trait:存在可行重载且选中的是被删除的函数
template <typename... Args>
struct foo_is_deleted : std::bool_constant<has_viable_overload<Args...>::value && !is_callable<Args...>::value> {};

template <typename... Args>
constexpr bool foo_is_deleted_v = foo_is_deleted<Args...>::value;

// 测试用例
static_assert(!foo_is_deleted_v<>);             // 存在且未被删除
static_assert( foo_is_deleted_v<double>);       // 显式删除
static_assert( foo_is_deleted_v<float>);        // float隐式转换到double,选中被删除的重载
static_assert(!foo_is_deleted_v<const char*>);  // const char*隐式转换到std::string,选中未被删除的重载
static_assert(!foo_is_deleted_v<std::vector<int>>); // 无可行重载,返回false
static_assert(!foo_is_deleted_v<char, char>);   // 歧义重载,返回false

原理说明

  1. has_viable_overload:

    • 利用std::void_t检测decltype(foo(std::declval<Args>()...))是否合法:
      • 如果重载决议能选出唯一函数(无论是否被删除),函数返回类型确定,decltype表达式合法,trait返回true;
      • 如果无可行重载或存在歧义,重载决议失败,decltype表达式非法,trait返回false。
  2. is_callable:

    • 同样利用std::void_t,直接检测调用表达式foo(std::declval<Args>()...)是否合法:
      • 若选中的重载未被删除,调用合法,trait返回true;
      • 若选中的重载被删除,调用触发编译错误(SFINAE语境下视为替换失败),trait返回false;
      • 无可行重载或歧义时,同样返回false。
  3. foo_is_deleted:

    • 结合前两个trait:当存在可行重载且选中的重载不可调用时,说明选中了被删除的函数,返回true;其他情况均返回false。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 21:05:22