gpt4 book ai didi

c++ - 让 SFINAE 在重载的函数对象上使用 `is_callable`

转载 作者:搜寻专家 更新时间:2023-10-31 00:29:06 25 4
gpt4 key购买 nike

考虑以下函数对象 l :

auto l = [](auto x){ x.foo(); };

我可以成功static_assert它可以用具有 .foo() 的类型调用成员函数:

struct Foo { void foo(); };
static_assert(std::is_callable<decltype(l)(Foo)>{});

我现在想要 std::is_callable评估为 std::false_type如果我使用的类型没有 .foo()成员函数:

static_assert(!std::is_callable<decltype(l)(int)>{});

不幸的是,以上static_assert导致编译错误:

prog.cc: In instantiation of '<lambda(auto:1)> [with auto:1 = int]':
prog.cc:8:44: required by substitution of 'template<class TF, class ... Ts>
struct is_callable<TF(Ts ...),
std::void_t<decltype (declval<TF>()((declval<Ts>)()...))>
> [with TF = <lambda(auto:1)>; Ts = {int}]'
prog.cc:17:50: required from here
prog.cc:12:24: error: request for member 'foo' in 'x', which is of non-class type 'int'
auto l = [](auto x){ x.foo(); };
~~^~~

我也尝试实现自己的 is_callable通过使用 std::void_t如下,得到同样的编译错误:

template <typename, typename = void>
struct is_callable : std::false_type { };

template <typename TF, class... Ts>
struct is_callable<TF(Ts...),
std::void_t<decltype(std::declval<TF>()(std::declval<Ts>()...))>>
: std::true_type { };

我的印象是 std::false_type如果 std::void_t<decltype(/* ... */)> 中的表达式将被选择由于 SFINAE 而无效。

  • 为什么这个 SFINAE 没有发生在这里,导致编译错误?

  • 我怎样才能实现我想要的行为? (即,如果调用重载函数对象的格式不正确,则计算结果为 std::false_type)

    • 请注意,在我的真实用例中,我将无法访问我正在执行 is_callable函数对象 的实现。检查。

live example on wandbox (C++14 compliant)

最佳答案

您的 lambda 不限制它与 sfinae 的参数。您的 lambda 可以用任何东西调用,但在使用这些参数实例化时会触发硬编译错误。

要获得预期的效果,请对返回类型施加约束:

auto l = [](auto x) -> void_t<decltype(x.foo())> { x.foo(); };

这样,is_callable 特性将产生正确的结果。

关于c++ - 让 SFINAE 在重载的函数对象上使用 `is_callable`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42739837/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com