为什么 std::less 是一个函子
why is std::less a functor?
为什么少了一个函子,而不是像下面myless这样的模板化函数?为什么委员会决定这样做,我可以去哪里进一步阅读?C++11标准是否解释了委员会做出某些决定的原因?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#if 1
template <class T> struct stdless {
bool operator() (const T& x, const T& y) const {return x<y;}
typedef T first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
};
#else
#define stdless std::less
#endif
//bool myless(int a, int b) { return a<b; }
template<class T>
bool myless(T a, T b) { return a<b; }
int main()
{
vector<int> a{5, 3, 1,6};
myless(5, 6);
stdless<int>()(5, 6);
auto fn1=stdless<int>();
fn1(5,9);
auto fn2=myless<int>;
fn2(5,9);
sort(a.begin(), a.end(), myless<int>);
sort(a.begin(), a.end(), less<int>());
for(auto b=a.begin(); b!=a.end(); ++b)
cout << *b<<endl;
}
这有不同的原因。第一个是,编译器在函子上内联对operator()
的调用比通过指向函数的指针内联调用更容易(当执行调用的代码本身未内联时)。
除了这种性能优势之外,对于std::less<>
函子的不同用途,手头还有更大的设计考虑因素。特别要考虑任何已分类的容器,例如 std::set<T,Comparator>
。你不能将指针直接作为类型传递函数,所以为了能够使用你的myless
集合的定义必须std::set<T,bool (*)(T,T)>
,现在这里的下一个问题是指针没有明智的默认构造函数来做你想要的,所以用户代码必须在容器的构造上提供函数指针, 这是潜在的错误。
std::set<int, bool(*)(int,int)> s(&myless);
忘记传递函数指针(std::set<int,bool(*)(int,int)> s;
)很简单,这会让你得到错误的指针并导致未定义的行为。在函子的情况下,这不是问题,编译器将默认构造比较器成员,这将是一个有效的对象。
相关文章:
- 库函数需要一个 std::function<void(void)>,如何传入类函数?
- 将 std::array 移动到另一个 std::array
- 为什么 Clang std::ostream 写一个 std::istream 无法读取的双精度?
- 访问 std:vector 的类成员 std:vector 在一个类中与另一个 std:vector
- 是否有一个 std::set 函数来确定不超过数字 x 的最大元素?
- 除了 std::vector 之外,是否有一个 std 容器不会复制和销毁作为类的元素?
- 我正在将一个 std::string 传递给一个 boost 函数,该函数对该类型进行常量引用,但该值发生了变化
- 在线程 A 中创建一个 std::thread 对象,在线程 B 中连接
- 使用 glDrawElements 绘制一个 std::vector
- 从 C 字符串构造 std::string 与从另一个 std::string 构造 std::string 不一致
- 我可以得到一个字符 * 到一个 std::sregex_iterator 匹配 str() 吗?
- 如何有效地将(一些)项目从一个std::map移动到另一个std::map
- 我可以制作一个std::set的constexpr对象吗
- 打印一个带有静态 int 的函数,有一个 std::cout 和多个 std::cout 有什么区别?
- Visual Studio 2017 STL 可视化工具失败了一个 std::map<MyIntrusivePtr, std::tuple<....> >
- 如何设置一个 std::vector 与另一个,其中两个是不同类的向量?
- SWIG:传递一个 std::vector< std::vector <double> >指向 python 的指针
- 如何构造一个 std::variant 类型对象,其自身 Templated 和构造函数转发参数
- 如何声明一个 std::用不同值内联初始化的结构数组
- 将对象从一个 std::d eque 移动到另一个的更好方法