如何检查一个类是否有一个模板调用运营商不知道它的返回类型? [重复]

问题描述 投票:-1回答:1

这个问题已经在这里有一个答案:

我有一个模板函数

template <typename F, typename T> auto foo(F f) { ... }

在这个函数中,我要排序,调用F:我想打电话给F.template operator()<T>(),不带参数的 - 但只有当它的存在。否则,我就要回型my_type_t的一些价值。

我读过这个问题:

Check if a class has a member function of a given signature

和更新:

Using `void_t` to check if a class has a method with a specific signature

和他们的答案。然而,他们似乎都认为你预先知道签名,因此你可以使用std::is_same以确保该方法确实存在,并产生相关的类型。

在我的情况 - 我不知道是什么类型的检查它反对。

所以,我能做些什么,不作任何这种假设的?

c++ c++14 template-meta-programming typetraits
1个回答
-1
投票

作为评论者建议(感谢@DanHulme),这是可行的与SFINAE没有任何假设 - 它在做的方式类似

Find out whether a C++ object is callable

至少,在一定的假设。

然而,这是需要一点技巧,以获得正确的代码为模板operator(),因为C ++的语法歧义。我也有些意见加入到简单介绍一下如何SFINAE在这里工作,有利于少-C ++的 - 精明的读者(的代码没有这个问题)。

总之,这里的适应:

#include <type_traits>

namespace detail {    

template <class>
struct sfinae_true : std::true_type{};

template <class F, typename T>
static auto test_invoke_operator(int ) ->
    sfinae_true<decltype(std::declval<F>().template operator()<T>())>;

template <class, typename>
static auto test_invoke_operator(long) -> std::false_type;

} // namespace detail

template <class F, typename T>
struct has_invoke_operator : decltype( detail::test_invoke_operator<F,T>(int{}) )
{ };
    // The overload resolution here will depend on the test for invoke_operator:
    // * If F has an operator()<T>, the `int` variant substitution succeeds,
    //   so has_invoke_operator inherits true_type.
    // * If F does not have an operator()<T>, the `int` variant substitution fails,
    //   but we still get a matching candidate - the `long` variant, which
    //   means has_invoke_operator inherits false_type

Working example on Coliru

在Coliru例子 - 我们需要用= delete该类没有任何其他专门的定义,也没有一个通用的定义来表示。

© www.soinside.com 2019 - 2024. All rights reserved.