指向功能和std ::功能:第一个编译而不是第二个指针

Pointer to function and std::function : the first one compiles and not the second one?

本文关键字:功能 第二个 指针 第一个 std 编译      更新时间:2023-10-16

我对函数的指针不熟悉,目前正在进行一些测试。但是在以下程序中,我不明白为什么第一个版本有效,以及为什么第二版不编译。正确的语法是什么?

#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)>'

功能指针提供我所说的转换上下文。它明确说明了哪种过载是指std::functionstd::function的构造函数接收任何可呼叫的实体,因此,没有任何上下文来消除歧义哪种超载。另请参阅此问题。

要手动放弃歧义,要么施放功能指针

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); });
相关文章: