【问题标题】:Pointer to function and std::function : the first one compiles and not the second one?指向函数和 std::function 的指针:第一个编译而不是第二个?
【发布时间】:2012-11-05 04:22:52
【问题描述】:

我不熟悉函数指针,目前正在做一些测试。但是在下面的程序中,我不明白为什么第一个版本可以工作,为什么第二个版本不能编译。正确的语法是什么?

#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>

template<typename Type> 
void display(const std::vector<Type>& v)
{
    if (!v.empty()) {
        for (unsigned int i = 0; i < v.size()-1; ++i)
            std::cout<<v[i]<<" ";
        std::cout<<v[v.size()-1];
    }
}

// Compiles 
template<typename Type> 
void apply1(std::vector<Type>& v, void(f)(Type*, Type*, Type))
{
    f(&*v.begin(), &*v.end(), 0);
}

// Does not compile
template<typename Type> 
void apply2(std::vector<Type>& v, std::function<void(Type*, Type*, Type)> f)
{
    f(&*v.begin(), &*v.end(), 0);
}

int main()
{
    std::vector<double> v = {1., 2., 3., 4., 5., 6.};
    display(v); std::cout<<std::endl;
    apply1(v, std::iota);
    display(v); std::cout<<std::endl;
    apply2(v, std::iota);
    display(v); std::cout<<std::endl;
    return 0;
}

错误如下:

error: cannot resolve overloaded function 'iota' based on conversion to type 'std::function<void(double*, double*, double)>'

【问题讨论】:

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


    【解决方案1】:

    函数指针提供了我所说的转换上下文。它明确说明了哪些重载是指,而std::function 没有。 std::function 的构造函数接受任何可调用的实体,因此不提供上下文来区分意味着哪个重载。另见this question

    要手动消除歧义,请转换函数指针

    apply2(v, static_cast<void(*)(double*,double*,double)>(std::iota));
    

    或使用命名函数指针

    void (*iota)(double*, double*, double) = std::iota;
    apply2(v, iota);
    

    或使用 lambda

    apply2(v, [](double* f, double* l, double d){ std::iota(f, l, d); });
    

    【讨论】:

    • 那么我该如何修改apply2 或其调用以传递std::iota 之类的算法?
    • 谢谢。但我还有另一个问题:在我调用函数而不是函数模板的情况下:这两个实现是否“等效”(除了 std::function 更“强大”)?
    • @Vincent:我猜这取决于你定义为 equivalent 的内容。 std::function 可以包含任何可调用实体,但也有间接性和可能的​​分配开销。
    猜你喜欢
    • 1970-01-01
    • 2018-04-23
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多