【发布时间】:2020-07-20 03:18:56
【问题描述】:
如果可调用模板参数不能通过std::apply 调用,我希望能够禁用函数。
也许从有效的方法开始解释问题会有所帮助。我有这个用于常规函数调用案例:
template <class Fn, class... Args>
using enable_if_callable = decltype(std::declval<Fn>()(std::declval<Args>()...));
...
template <class Fn, class = enable_if_callable<Fn, int, float>>
void call_fn(Fn fn) {
fn(1, 2.0f);
}
// The above is correctly disabled in this case:
call_fn([](int) {})
当不能使用参数(int, float) 调用fn 时,上述方法可以很好地禁用call_fn。正如预期的那样,我在实例化站点只收到一个错误。
如果在 std::tuple 中指定了 Args,我正在尝试找到禁用函数的等效项,以便与 std::apply 一起使用:
template <class Fn, class TupleArgs>
using enable_if_applicable =
decltype(std::apply(std::declval<Fn>(), std::declval<TupleArgs>()));
...
template <class Fn, class = enable_if_applicable<Fn, std::tuple<int, float>>>
void apply_fn(Fn fn) {
std::apply(fn, std::make_tuple(1, 2.0f));
}
// The above is not correctly disabled in this case:
apply_fn([](int) {})
这不会阻止实例化,至少不会避免来自 apply 内部的错误,大概是因为这些错误不是来自声明的替换失败。我熟悉的剥离元组的技术似乎不适用于这里(索引序列等)。
当然,在这个非通用示例中,仅使用 enable_if_callable<Fn, int, float> 就可以了,但是当元组可以包含任意数量的元素时,我会尝试使其工作。
关于如何实现这样的事情有什么想法吗?
【问题讨论】:
-
感谢收看。我尝试稍微改写一下,并将示例函数调整为具体而不是通用,希望使其更易于理解。
标签: c++ variadic-templates sfinae stdtuple