下标运算符要有const与非const重载两种版本。
struct absInt {
int operator()(int val) const {
return val < 0 ? -val : val;
}
};
//函数对象,如同一个lambda
int main() {
int i = -42;
absInt absObj; // object that has a function-call operator
unsigned ui = absObj(i); // passes i to absObj.operator()
cout << i << " " << ui << endl;
// store collection of positive and negative integers in vi
vector<int> vi;
while (cin >> i)
vi.push_back(i);
// call absInt to store the absolute value of those ints in vu
vector<unsigned> vu;
transform(vi.begin(), vi.end(), back_inserter(vu), absInt());
// print contents of vu using a lambda
for_each(vu.begin(), vu.end(), [](unsigned i) { cout << i << " "; });
cout << endl;
vector<unsigned> vu2;
// similar transformation but using a lambda
transform(vi.begin(), vi.end(), back_inserter(vu2),
[](int i) { return i < 0 ? -i : i; });
if (vu == vu2)
cout << "as expected" << endl;
else {
cout << "something's wrong, vectors differ" << endl;
for_each(vu.begin(), vu.end(), [](unsigned i) { cout << i << " "; });
}
cout << endl;
return 0;
}
lambda有捕获列表,对于函数对象来讲,就是要提供一个初始值来进行构造
#include <utility>
using std::make_pair;
#endif
// ordinary function
int add(int i, int j) { return i + j; }
// lambda, which generates an unnamed function-object class
auto mod = [](int i, int j) { return i % j; };
// function-object class
// In the first printing we named this struct div, but this name conflicts with
// the name of a C library function. Compilers are permitted to put
// C library names in the global namespace. Future printings will
// change the name of this calss to divide.
struct divide {
int operator()(int denominator, int divisor) {
return denominator / divisor;
}
};
int main()
{
function<int(int, int)> f1 = add; // function pointer
function<int(int, int)> f2 = divide(); // callable class type
function<int(int, int)> f3 = [](int i, int j) // lambda
{ return i * j; };
cout << f1(4,2) << endl; // prints 6
cout << f2(4,2) << endl; // prints 2
cout << f3(4,2) << endl; // prints 8
// table of callable objects corresponding to each binary operator
// all the callables must take two ints and return an int
// an element can be a function pointer, function object, or lambda
#ifdef LIST_INIT
map<string, function<int(int, int)>> binops = {
{"+", add}, // function pointer
{"-", std::minus<int>()}, // library function object
{"/", divide()}, // user-defined function object
{"*", [](int i, int j) { return i * j; }}, // unnamed lambda
{"%", mod} }; // named lambda object
#else
map<string, function<int(int, int)>> binops;
binops.insert(make_pair("+", add)); // function pointer
binops.insert(make_pair("-", std::minus<int>())); // library function object
binops.insert(make_pair("/", divide())); // user-defined function object
binops.insert(make_pair("*", [](int i, int j) { return i * j; })); // unnamed lambda
binops.insert(make_pair("%", mod)); // named lambda object
#endif
cout << binops["+"](10, 5) << endl; // calls add(10, 5)
cout << binops["-"](10, 5) << endl; // uses the call operator of the minus<int> object
cout << binops["/"](10, 5) << endl; // uses the call operator of the divide object
cout << binops["*"](10, 5) << endl; // calls the lambda function object
cout << binops["%"](10, 5) << endl; // calls the lambda function object
return 0;
}
如果一个函数存在多个重载版本,那么function对象构造时不能直接使用函数名。可以先构造一个函数指针,在用函数指针解引用来构造。
二义性转换:
1.A类型定义了一个接受B的转换构造函数,B类型定义了一个目标类型是A的转换运算符。
2.定义了多个转换规则,而这些转换涉及的类型相互之间有所联系。(int 与double)
当调用重载函数时,如果用户定义的多种类型都定义了可行匹配,我们认为这些匹配一样好。