【问题标题】:std::function and error: no matching function for call tostd::function 和错误:没有匹配的调用函数
【发布时间】:2017-02-21 12:20:32
【问题描述】:

我正在调用一个基于模板的函数,它在函数和结构之间共享一个类型。这段代码有什么问题?为什么编译的时候会报错?

test.cpp

#include <functional>
#include <iostream>

template<typename T>
struct mystruct
{
    T variable;
};

int myfunc(int x)
{
    return 2*x;
}

template<typename T>
T calculate(
    mystruct<T> custom_struct,
    std::function<T(T)> custom_func)
{
    return custom_func(custom_struct.variable);
}

int main()
{
    mystruct<int> A;
    A.variable=6;
    std::cout<<calculate(A,myfunc)<<std::endl;
    return 0;
}

编译结果:

test.cpp:25:31: error: no matching function for call to ‘calculate(mystruct<int>&, int (&)(int))’
  std::cout<<calculate(A,myfunc)<<std::endl;
                               ^

【问题讨论】:

    标签: c++ c++11 templates std-function


    【解决方案1】:

    没有理由使用std::function 包装器。而是使用通用模板参数F

    template<typename T, class F>
    T calculate(
        mystruct<T> custom_struct,
        F custom_func)
    {
        return custom_func(custom_struct.variable);
    }
    

    Live Example

    请注意,您还忘记访问呼叫站点上的variable 成员。 由于您在这里进行泛型编程,因此您还希望返回类型等于T,甚至是auto(C++14,对于C++11,您可能需要使用decltype,但这太多了重复)。

    【讨论】:

    • 我也会修复 int 返回类型
    【解决方案2】:

    你的代码有点乱,但总有解决办法。

    #include <functional>
    #include <iostream>
    
    template<typename T>
    struct mystruct
    {
        T variable;
    };
    
    const int myfunc(const int & x)
    {
        return 2*x;
    }
    
    template<typename T>
    T calculate(
        mystruct<T> custom_struct,
        std::function<T(T)> custom_func)
    {
        return custom_func(custom_struct.variable);
    }
    
    int main()
    {
        mystruct<int> A;
        A.variable=6;
        std::cout<<calculate<int>(A,myfunc)<<std::endl;
        return 0;
    }
    

    return custom_func(custom_struct) 存在问题,您必须从该结构中传递 variable 成员并添加 calculate&lt;int&gt; 而不是 calculate

    您可以在这里尝试/测试新代码:http://cpp.sh/33cpn

    【讨论】:

      【解决方案3】:
      template<typename T>
      int calculate(
          mystruct<T> custom_struct,
          std::function<T(T)> custom_func);
      

      编译器将尝试从std::function&lt;T(T)&gt;mystruct&lt;T&gt; 推导出T,但从函数指针推导失败。一种解决方案是通过将std::function&lt;T(T)&gt; 设为非推断上下文来禁用模板推断:

      template <typename T> struct identity { using type = T; };
      template <typename T> using identity_t = typename identity<T>::type; 
      
      template<typename T>
      int calculate(
          mystruct<T> custom_struct,
          identity_t<std::function<T(T)>> custom_func)
      {
          return custom_func(custom_struct.variable);
      }
      

      虽然它使函数签名有点难看,但你仍然可以推导出T,所以你可以直接调用calculate(A,myfunc)而不是calculate&lt;int&gt;(A,myfunc)

      但是,在这种情况下,您应该使用 TemplateRex's solution,因为 std::function 会带来大量开销,除非您想将其存储在某个地方,否则您实际上并不需要这些开销。

      【讨论】:

        【解决方案4】:

        您在calculate() 中错误地将custom_struct 传递给custom_func

        尝试通过 custom_struct.variable 代替:

        template<typename T>
        int calculate(
            mystruct<T> custom_struct,
            std::function<T(T)> custom_func)
        {
            return custom_func(custom_struct.variable);
        }
        

        同样在ideone

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-05-26
          • 2018-10-23
          • 1970-01-01
          • 2014-11-29
          • 2015-06-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多