求助:STL 算法为什么推不出所需要的重载的op函数

2024-06-16 23:48

本文主要是介绍求助:STL 算法为什么推不出所需要的重载的op函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

例如:

print是重载的,find_if既然需要的是一元谓词,为什么不能推出需要的接受一个参数的print? 

代码如下:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;bool print(int a)
{cout << "para 1:" << a << endl;return a > 0;
}bool print(int a, int b)
{cout << "para 1:" << a << ", para 2:" << b << endl;return a > b;
}int main()
{// 能推出重载的函数bool res = print(1);cout << "res:" << res << endl;vector<int> tes = {-1, -2, 1, 2};auto itbegin = tes.begin();// 为什么stl算法不能识别重载的函数?auto it = find_if(tes.begin(), tes.end(), print);// 指明类型就可以//auto it = find_if(tes.begin(), tes.end(), (bool (*)(int))(print));cout << "len:" << it - itbegin << endl;return 0;
}

编译报错如下:


> Executing task: C:\TDM-GCC-64\bin\g++.exe -g e:\Code\YiliyoProject\We_Code_CPP\sourcefile\test_tolower.cpp -o e:\Code\YiliyoProject\We_Code_CPP\sourcefile\test_tolower.exe <e:\Code\YiliyoProject\We_Code_CPP\sourcefile\test_tolower.cpp: In function 'int main()':
e:\Code\YiliyoProject\We_Code_CPP\sourcefile\test_tolower.cpp:32:52: error: no matching function for call to 'find_if(std::vector<int>::iterator, std::vector<int>::iterator, <unresolved overloaded function type>)'32 |     auto it = find_if(tes.begin(), tes.end(), print);|                                                    ^
In file included from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/algorithm:62,from e:\Code\YiliyoProject\We_Code_CPP\sourcefile\test_tolower.cpp:2:
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/bits/stl_algo.h:3915:5: note: candidate: 'template<class _IIter, class _Predicate> _IIter std::find_if(_IIter, _IIter, _Predicate)'3915 |     find_if(_InputIterator __first, _InputIterator __last,|     ^~~~~~~
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/bits/stl_algo.h:3915:5: note:   template argument deduction/substitution failed:
e:\Code\YiliyoProject\We_Code_CPP\sourcefile\test_tolower.cpp:32:52: note:   couldn't deduce template parameter '_Predicate'32 |     auto it = find_if(tes.begin(), tes.end(), print);|                                                    ^
终端进程已终止,退出代码: 1

注:此问题是对transform(s.begin(), s.end(), isalpha);编译报错的解释。

直接写isalpha会在std命名空间找到cctype和clocate两个文件中找到两个重载的isalpha函数。而写成::isalpha会在全局命名空间中找isalpha函数,全局命名空间中只有一个ctype.h中的isalpha函数,因此可以正确运行。

原因:模板实例化时,需要传确定类型的实参。

知识点:

(1)重载函数的指针

void ff(int*);

void ff(unsigned int);

void (*fp1)(unsigned int) = ff;

编译器通过指针类型决定选用那个函数,指针类型与重载函数中的某一个精确匹配。(根据目的的类型选择具体的)。

(2)模板类型的推断

根据实参的类型推断模板参数的类型。(根据源的类型确定目的得类型)。这与根据目的类型选择具体的重载函数矛盾。

sdghchj的回复:

那如果还有bool print(float a) 呢?
隐式调用模板是根据确定的模板实参(包括类型)推导生成出你想调用的模板函数,还没做到根据你想调用的模板函数来反推模板实参的具体类型那么智能。
auto it = find_if<vector<int>::iterator, bool(int)>(tes.begin(), tes.end(), print);
或者
auto it = find_if(tes.begin(), tes.end(), (bool(*)(int))&print);

或用lambda来写确定函数对象

auto it = find_if(tes.begin(), tes.end(),static_cast<bool (*)(int)>(print));

auto it = find_if(tes.begin(), tes.end(), [](int a) {return print(a); });

 

 

这篇关于求助:STL 算法为什么推不出所需要的重载的op函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1067899

相关文章

【操作系统】信号Signal超详解|捕捉函数

🔥博客主页: 我要成为C++领域大神🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 如何触发信号 信号是Linux下的经典技术,一般操作系统利用信号杀死违规进程,典型进程干预手段,信号除了杀死进程外也可以挂起进程 kill -l 查看系统支持的信号

java中查看函数运行时间和cpu运行时间

android开发调查性能问题中有一个现象,函数的运行时间远低于cpu执行时间,因为函数运行期间线程可能包含等待操作。native层可以查看实际的cpu执行时间和函数执行时间。在java中如何实现? 借助AI得到了答案 import java.lang.management.ManagementFactory;import java.lang.management.Threa

代码随想录算法训练营:12/60

非科班学习算法day12 | LeetCode150:逆波兰表达式 ,Leetcode239: 滑动窗口最大值  目录 介绍 一、基础概念补充: 1.c++字符串转为数字 1. std::stoi, std::stol, std::stoll, std::stoul, std::stoull(最常用) 2. std::stringstream 3. std::atoi, std

人工智能机器学习算法总结神经网络算法(前向及反向传播)

1.定义,意义和优缺点 定义: 神经网络算法是一种模仿人类大脑神经元之间连接方式的机器学习算法。通过多层神经元的组合和激活函数的非线性转换,神经网络能够学习数据的特征和模式,实现对复杂数据的建模和预测。(我们可以借助人类的神经元模型来更好的帮助我们理解该算法的本质,不过这里需要说明的是,虽然名字是神经网络,并且结构等等也是借鉴了神经网络,但其原型以及算法本质上还和生物层面的神经网络运行原理存在

SQL Server中,isnull()函数以及null的用法

SQL Serve中的isnull()函数:          isnull(value1,value2)         1、value1与value2的数据类型必须一致。         2、如果value1的值不为null,结果返回value1。         3、如果value1为null,结果返回vaule2的值。vaule2是你设定的值。        如

tf.split()函数解析

API原型(TensorFlow 1.8.0): tf.split(     value,     num_or_size_splits,     axis=0,     num=None,     name='split' ) 这个函数是用来切割张量的。输入切割的张量和参数,返回切割的结果。  value传入的就是需要切割的张量。  这个函数有两种切割的方式: 以三个维度的张量为例,比如说一

大林 PID 算法

Dahlin PID算法是一种用于控制和调节系统的比例积分延迟算法。以下是一个简单的C语言实现示例: #include <stdio.h>// DALIN PID 结构体定义typedef struct {float SetPoint; // 设定点float Proportion; // 比例float Integral; // 积分float Derivative; // 微分flo

BD错误集锦8——在集成Spring MVC + MyBtis编写mapper文件时需要注意格式 You have an error in your SQL syntax

报错的文件 <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.yuan.dao.YuanUserDao"><!

神经网络第三篇:输出层及softmax函数

在上一篇专题中,我们以三层神经网络的实现为例,介绍了如何利用Python和Numpy编程实现神经网络的计算。其中,中间(隐藏)层和输出层的激活函数分别选择了 sigmoid函数和恒等函数。此刻,我们心中不难发问:为什么要花一个专题来介绍输出层及其激活函数?它和中间层又有什么区别?softmax函数何来何去?下面我们带着这些疑问进入本专题的知识点: 1 输出层概述 2 回归问题及恒等函数 3

神经网络第一篇:激活函数是连接感知机和神经网络的桥梁

前面发布的文章介绍了感知机,了解了感知机可以通过叠加层表示复杂的函数。遗憾的是,设定合适的、能符合预期的输入与输出的权重,是由人工进行的。从本章开始,将进入神经网络的学习,首先介绍激活函数,因为它是连接感知机和神经网络的桥梁。如果读者认知阅读了本专题知识,相信你必有收获。 感知机数学表达式的简化 前面我们介绍了用感知机接收两个输入信号的数学表示如下: