C++ Can';没有一种方法存在检测机制可以工作

C++ Can';没有一种方法存在检测机制可以工作,c++,c++14,template-meta-programming,conditional-compilation,C++,C++14,Template Meta Programming,Conditional Compilation,我正在编写模板化代码,它需要调用它得到的某个函数的模板化操作符(),但前提是该操作符()存在 我编写了以下代码: template <typename> struct sfinae_true : std::true_type{}; template <class F, typename T, typename... Us> static auto test_templated_invoke_operator(int) -> sfinae_true<

我正在编写模板化代码,它需要调用它得到的某个函数的模板化
操作符()
,但前提是该
操作符()
存在

我编写了以下代码:


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

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

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

template <class F, typename T, typename... Us>
struct has_templated_invoke_operator : decltype( test_templated_invoke_operator<F, T, Us...>(int{}) )
{ };

template <bool ActuallyInvoke, typename R, class F, typename T, typename... Ts>
struct invoke_if_possible_inner;

template <class F, typename R, typename T, typename... Ts>
struct invoke_if_possible_inner<false, R, F, T, Ts...>
{
    R operator()(F, Ts&&...) { 
        return R(); 
    }
};

template <class F, typename R, typename T, typename... Ts>
struct invoke_if_possible_inner<true, R, F, T, Ts...>
{
    R operator()(F functor, Ts&&... params)
    {
        return functor.template operator()<T>(std::forward<Ts>(params)...);
    }
};

template <typename T, typename R>
struct invoke_if_possible {
    template <class F, typename... Ts>
    R operator()(F functor, Ts&&... params)
    {
        constexpr bool actually_invoke = has_templated_invoke_operator<F, T, Ts...>::value;
        // static_assert(actually_invoke == true,"Should be able to invoke for now!");
        return invoke_if_possible_inner<actually_invoke, R, F, T, Ts...>{}(functor, std::forward<Ts>(params)...);
    }
};
这个(Coliru)-返回0.0而不是6.0

我的问题是:为什么代码不调用已定义的运算符()?我如何修复检测机制,从而确认它的存在并调用它

注:

  • 模板参数T是任意的;它与
    Us
    参数无关
  • 是的,可以使用
    操作符()
    的返回类型派生R,但前提是它存在。所以我们只是提供它
  • 如果启用静态断言,它将失败
    • 您的问题在于:

      std::forward(std::declval<Us>())
      
      std::forward(std::declval())
      
      std::forward
      接受未提供的非推断模板参数-必须是
      forward(u)
      -因此其推断无条件失败

      但您甚至不需要在此处转发
      。只要
      declval()
      就足够了

      std::forward(std::declval<Us>())