| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1135 人关注过本帖
标题:怪异的funtion函数
只看楼主 加入收藏
Quants
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2023-5-17
收藏
 问题点数:0 回复次数:9 
怪异的funtion函数
C++ primer上介绍了std::function的用法,尝试写一个简单的应用

int half(int i)
{
    return i / 2;
}

function<int(int)> fn1 = half;
function<int(int)> fn2 = &half;

编译可以通过。但是我写入以下代码:

int add(int i, int j)
{
    return i + j;
}

function<int(int, int)> fn3 = add;

编译时报错:error C2440: 'initializing': cannot convert from 'overloaded-function' to 'std::function<int (int,int)>'

看起来几乎是一样的用法,请问是哪里出错了?
搜索更多相关主题的帖子: function int std half 函数 
2023-05-17 09:23
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:0 
所以,你为什么不肯贴出完整的代码呢?比如
程序代码:
#include <functional>
using namespace std;

int add(int i, int j)
{
    return i + j;
}

int main( void )
{
    std::function<int(int,int)> fn3 = add;
}


从 cannot convert from 'overloaded-function' to 'std::function<int (int,int)> 来看,出问题的代码可能在你不肯贴出来的代码中,比如
程序代码:
#include <functional>
using namespace std;

int add( int i )
{
    return i;
}
int add( int i, int j )
{
    return i + j;
}

int main( void )
{
    std::function<int(int,int)> fn3 = add; // 编译器不知道这个 add 是 int add(int) 还是 int add(int,int)
}


解决办法:
程序代码:
#include <iostream>
#include <functional>
using namespace std;

int add( int i )
{
    return i;
}
int add( int i, int j )
{
    return i + j;
}

int main( void )
{
    std::function<int(int,int)> fn3 = static_cast<int (*)(int,int)>( add );
    cout << fn3(1,2) << endl;

    std::function<int(int,int)> fn4 = [](int i, int j)->decltype(auto) { return add(i,j); };
    cout << fn4(2,3) << endl;
}


[此贴子已经被作者于2023-5-17 09:54编辑过]

2023-05-17 09:48
Quants
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2023-5-17
收藏
得分:0 
C++上的一道例题,目的是做一个简单的计算器。
完整的代码如下:
程序代码:
#include <functional>
#include <iostream>
#include <map>
#include <string>

using namespace std;

int add(int i, int j)
{
    return i + j;
}

int half(int i)
{
    return i / 2;
}

int main()
{
    function<int(int)> fn1 = half;
    function<int(int)> fn2 = &half;
    function<int(int, int)> fn3 = add;

    map<string, function<int(int, int)>> op =
    {
        "+",add
    };

    cout << fn1(60) << endl;

    return 0;
}


function<int(int, int)> fn3 = add;编译能通过,但问题出在op的初始化,提示:error C2440: 'initializing': cannot convert from 'initializer list' to 'std::map<std::string,std::function<int (int,int)>,std::less<std::string>,std::allocator<std::pair<const std::string,std::function<int (int,int)>>>>'

看起来写法几乎是一样,为什么function<int(int, int)> fn3 = add;能通过,但是初始化语句却不行?

[此贴子已经被作者于2023-5-17 10:15编辑过]

2023-05-17 10:13
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:0 
map<string, function<int(int, int)>> op = { "+", add };
改为
map<string, function<int(int, int)>> op = { {"+",add} };
2023-05-17 12:37
Quants
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2023-5-17
收藏
得分:0 
上面的问题解决了。但是当我包含一个头文件后,代码又不能编译出错了
Sales_data.h
程序代码:
#ifndef SALES_DATA_H
#define SALES_DATA_H

#include <iostream>
#include <string>

class Sales_data
{
    friend std::istream& read(std::istream&, Sales_data&);
    friend std::ostream& print(std::ostream&, const Sales_data&);
    friend Sales_data add(const Sales_data&, const Sales_data&);
public:
    Sales_data() : Sales_data("", 0, 0.0) { std::cout << "Sales_data()" << std::endl; }
    Sales_data(std::string& s) :Sales_data(s, 0, 0.0) { std::cout << "Sales_data(std::string &)" << std::endl; }
    Sales_data(std::string s, unsigned n, double p) :bookNo(s), units_sold(n), revenue(n* p) { std::cout << "Sales_data(std::string &,unsigned n,double p)" << std::endl; }
    Sales_data(std::istream& is) : Sales_data("", 0, 0.0) { read(is, *this); }

    std::string isbn() const { return bookNo; }
    Sales_data& combine(const Sales_data&);
    double avg_price() const;
private:
    std::string bookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
};

std::istream& read(std::istream&, Sales_data&);
std::ostream& print(std::ostream&, const Sales_data&);
Sales_data add(const Sales_data&, const Sales_data&);

#endif


exercise.cpp
程序代码:
#include <map>
#include <functional>
#include <iostream>
#include <string>
#include "Sales_data.h"

using namespace std;

int add(int i, int j)
{
    return i + j;
}

int half(int i)
{
    return i / 2;
}

int main()
{
    map<string, function<int(int, int)>> binops = {
        {"+",add},
        {"-",minus<int>()},
        {"*",[](int i,int j) { return i * j; }},
        {"/",[](int i,int j) { return i / j; }}
    };

    map<string, int(*)(int, int)> binops2 =
    {
        {"+",add}
    };

    function<int(int, int)> fn3 = add;

    function<int(int)> fn1 = half;
    function<int(int)> fn2 = &half;

    cout << fn1(60) << endl;

    return 0;
}


提示:error C2440: 'initializing': cannot convert from 'initializer list' to 'std::map<std::string,std::function<int (int,int)>,std::less<std::string>,std::allocator<std::pair<const std::string,std::function<int (int,int)>>>>'

[此贴子已经被作者于2023-5-17 14:37编辑过]

2023-05-17 13:55
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:0 
回复 5楼 Quants
这个问题,一开始在2楼我就回答过你了。

你有两个 add 函数,
一个是 Sales_data.h 中的 Sales_data add(const Sales_data&, const Sales_data&);
一个是 exercise.cpp 中的 int add(int i, int j)。

解决手段我在2楼也给了,你回过头去看看。
2023-05-17 14:27
Quants
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2023-5-17
收藏
得分:0 
我有些不大明白,虽然函数名是一样的,都是add,但入参不同呀,一个是(int,int),另一个是const Sales_data&。按理说call signature不同,是能精确匹配的,不存在二义性。
2023-05-17 16:54
leeco
Rank: 4
等 级:贵宾
威 望:10
帖 子:1029
专家分:177
注 册:2007-5-10
收藏
得分:0 
编译器处理时候的先后顺序问题,在我的编译上报错是,先找的add,发现add有多个,直接就认为add的类型不能确定了
2023-05-17 17:44
Quants
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2023-5-17
收藏
得分:0 
以下是引用leeco在2023-5-17 17:44:28的发言:

编译器处理时候的先后顺序问题,在我的编译上报错是,先找的add,发现add有多个,直接就认为add的类型不能确定了


重载函数的匹配不就是这么一个过程吗?同名函数都是可行性函数,然后进行参数匹配以消除二义性。

[此贴子已经被作者于2023-5-17 19:11编辑过]

2023-05-17 19:06
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:0 
查看一下 std::function 的实现,可知对于 function<int(int, int)> fn3 = add; 是 先推断add的类型,然后判断此类型是否可转化成 int(int, int)
第一步就失败了,因为add是overload函数,类型不确定。

演示代码
程序代码:
int add( int i )
{
    return i;
}

int add( int i, int j )
{
    return i + j;
}

template<class T>
struct foo
{
    template<class U>
    foo( U&& fun )
    {
    }
};

int main( void )
{
    foo<int(int,int)> haha = add;
}
2023-05-17 20:16
快速回复:怪异的funtion函数
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019966 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved