如何使用 sfinae 排除定义了函数的类型?

Aar*_*ron 4 c++ decltype sfinae trailing-return-type

考虑如何使用decltype()尾随返回类型中的逗号表达式来检查是否可以应用函数:

template <class A>
auto f(A a) -> decltype(check_if_possible(a), return_type(a))
Run Code Online (Sandbox Code Playgroud)

如何否定逗号前的部分以排除check_if_possible(a)已定义的情况?

上下文: f()是不同的重载函数A。我想解决两个实现之间的歧义重载。其中一个使用check_if_possible(a),另一个在不能应用的情况下工作a

编辑:std::enable_if也欢迎使用和相关的东西,但我想避免额外的辅助功能/模板,因为有几个功能类似于f()具有不同启用条件的功能。如果这是不可能的,那么这也是一个答案;)

max*_*x66 5

如何否定逗号前的部分以排除定义了 check_if_possible(a) 的情况?

我不知道有什么办法,但是...

上下文:f 是不同 A 的重载函数。我想解决两个实现之间的歧义重载。其中一个使用 check_if_possible(a),另一个在不能应用于 a 的情况下工作。

我通常f()为这两种情况编写一个函数,这两种情况需要几个f_helper()函数接收一个额外的参数。

例如

template <typename A>
auto f (A && a)
 { return f_helper(std::forward<A>(a), 0); }
Run Code Online (Sandbox Code Playgroud)

观察最后一个参数:0,这是一个int

然后你可以编写check_if_possible()版本,收到额外的int

template <typename A>
auto f_helper (A a, int) -> decltype(check_if_possible(a), return_type(a))
 { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

和一个通用版本,始终启用,收到一个额外的 long

template <typename A>
auto f_helper (A a, long)
 { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

这样,当Asupport 时check_if_possible(),两者f_helper()都启用,但首选特定版本,因为0是 a int,特定版本接收附加int(完全匹配)和通用附加longint可转换为long但不是完全匹配)。

A不支持时check_if_possible(),只有泛型f_helper()可用。