您的位置:首页 > 其它

函数调用运算符与重载、类型转换

2017-02-05 15:11 381 查看
函数调用运算符:operator()

函数运算符必须是成员函数。一个类可以定义多个不同版本的调用运算符,相互之间应该在参数数量或类型上有所区别。如果类定义了调用运算符,则该类的对象称作函数对象

函数对象类除了operator之外还可以包含其他成员。这些成员通常用于定制调用运算符中的操作。

#include <iostream>
#include <string>
class A
{
public:
int operator()(bool a,int b,int c) const
{
if(a)
return b;
else
return c;
}
};
class GetInput
{
public:
GetInput(std::istream &i=std::cin):is(i){}
std::string operator()()const
{
std::string str;
std::getline(is,str);
return is?str:std::string();
}
private:
std::istream &is;
};
int main()
{
A a;
int ret=a(0,7,8);
std::cout<<ret<<std::endl;
GetInput gi;
std::cout<<gi()<<std::endl;
return 0;
}


lambda表达式相当于一个类含有函数调用符的对象。

stable_sort(words.begin(),words.end(),[](const string &a,const string &b){return a.size()<b.size()});
等价于
class shorterstring
{
public:
bool operator()(const string &a,const string &b) const
{
return a.size()<b.size()
}
}


标准库定义了一组表示算术运算符、关系运算符和逻辑运算符的类。这些类被定义成模板的形式。



#include <iostream>
#include <functional>

int main()
{
std::plus<int> intadd;
int sum=intadd(10,20);
std::cout<<sum;
return 0;
}


C++语言有几种可调用的对象:函数,函数指针,lambda表达式,bind创建的对象,重载的函数运算符的类。不同类型可能有相同的调用形式。在制作函数表的时候,我们可以利用function模板来实现不同类型而具有相同调用形式形成函数表。

#include <functional>
#include <iostream>
#include <map>
#include <string>

int add(int i,int j){return i+j;}
auto mod=[](int i,int j){return i%j;};
struct Div{ int operator ()(int i, int j) const { return i / j; } };
auto binops=std::map<std::string,std::function<int(int,int)>>
{
{"+",add},//加法,函数指针
{"%",mod},//求余,命名的lambda对象
{"/",Div()},//除法,函数对象类
{"-" ,std::minus<int>()},//减法,标准库函数对象
{"*",[](int i,int j){return i*j;}}//乘法,未命名的lambda对象
};

int main()
{
while ( std::cout << "Pls enter as: num operator num :\n", true )
{
int lhs, rhs; std::string op;
std::cin >> lhs >> op >> rhs;
std::cout << binops[op](lhs, rhs) << std::endl;
}

return 0;
}


类型转换运算符是类的一种特殊的成员函数,它负责将一个类类型的值转换成其他类型。一个类型转换函数必须是类的成员函数,它不能声明返回类型,形参列表也必须为空。类转换类型函数通常是const.

operator type() const;


类型转换运算符可能产生意外的结果,C++11新标准引入了显示的类型转换运算符

class SmallInt
{
explicit operator int() const{return val;}
}
SmallInt si=3;//正确
si+3;//错误,需要隐式类型转换,但类运算符是显式的
static_cast<int>(si)+3;//正确:显式地请求类型转换


向bool的类型转换通常用在条件部分,因此operator bool一般定义成explicit.

如果类中包含一个或多个类型,则必须确保在类类型和目标类型之间只存在唯一一种转换方式。

(1)实参匹配和相同的类型转换

struct B;
struct A
{
A()=default;
A(const B&);

};
struct B
{
operator A() const;
};
A f(const A&);
B b;
A a=f(b);//二义性错误:f(B::operator A()) ?f(A::A(const B&))
A a1=f(b.operator A());//正确:使用B的类型转换运算符
A a2=f(A(b));//正确:使用A的构造函数


(2)二义性与转换目标为内置类型的多重类型转换

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐