Luc*_*uca 9 c++ type-conversion c++11
我正在研究用C++转换构造函数和转换运算符.到目前为止我学到的是,任何只带一个参数(以及任意数量的可选默认参数)的非显式构造函数表示对THAT类类型的隐式类类型转换,例如,如果类定义了一个构造函数,类型intI的一个参数可以int在需要该类类型的对象的任何地方使用:
(假设class_type有一个重载的+ =运算符)
class_type a;
a+=5;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,5被隐式转换(通过转换构造函数),class_type并调用重载的运算符.
现在,(至少对我来说)棘手的部分:我知道我可以将转换运算符定义为成员函数:
operator int() {....};
Run Code Online (Sandbox Code Playgroud)
将对象转换为class_type基本int类型,我可以使用如下转换:
class_type a;
a+5;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我已经读过通过其转换运算符将对象转换为int,然后调用内置和运算符.但是如果我定义了一个重载的+运算符来将两个class_type对象作为其参数呢?就像是
class_type operator+(const class_type&,const class_type &c);
编译器如何知道通过函数匹配调用哪一个?int仅当定义了内置运算符时,转换是否仅隐式发生?
谢谢!
编辑:
实际上,我已经尝试编写一些代码来有效地尝试它,结果发现我的编译器(g ++)不会发出任何模糊的调用错误!
这是类头(以及非memeber操作符+函数声明):
#include <iostream>
class wrapper {
friend std::ostream &operator<<(std::ostream&,const wrapper&);
public:
wrapper()=default;
wrapper(int);
int get();
operator int() const;
wrapper operator+(int);
private:
int a=10;
};
std::ostream &operator<<(std::ostream&,const wrapper&);
Run Code Online (Sandbox Code Playgroud)
这是主要代码:
#include "wrapper.h"
int main()
{
using namespace std;
wrapper w1;
wrapper w2(5);
cout<<w1<<" "<<w2<<endl;
w1+1;
}
Run Code Online (Sandbox Code Playgroud)
现在,我已经定义从一个转换构造int,以wrapper与从类型的转换运算符int(我也重载以打印一些结果<<输出操作符),但是当编译器计算表达式w1+1它似乎是细.怎么可能?
Vla*_*cow 15
例如,如果您有包含转换构造函数和转换运算符的以下类声明
struct A
{
A( int x ) : x( x ) {}
operator int() const { return x; }
int x;
};
const A operator +( const A &a1, const A &a2 )
{
return A( a1.x + a2.x );
}
Run Code Online (Sandbox Code Playgroud)
声明
a1 + a2;
Run Code Online (Sandbox Code Playgroud)
其中a1和a2被声明为例如
A a1( 10 );
A a2( 20 );
Run Code Online (Sandbox Code Playgroud)
因为不需要调用转换函数,所以格式正确.两个操作数都匹配operator +的参数声明.
但是,如果你要写的话
a1 + 20;
Run Code Online (Sandbox Code Playgroud)
当编译器发出错误时,因为存在歧义.编译器可以应用转换构造函数A( int ) 将第二个操作数转换为类型,A并调用为类型对象定义的运算符A.或者它可以应用转换运算符operator int将第一个操作数转换为类型int并调用operator +类型对象的内置函数int.
为避免这种歧义,您可以使用函数说明符声明构造函数或运算符(或两者)explicit.
例如
explicit A( int x ) : x( x ) {}
Run Code Online (Sandbox Code Playgroud)
要么
explicit operator int() const { return x; }
Run Code Online (Sandbox Code Playgroud)
在这种情况下,只存在一个隐式转换,并且没有任何矛盾.
我想附加上面的描述,即使用函数说明符声明它们,有时也可以隐式调用某些转换运算符explicit.
例如根据C++标准(6.4选择语句)
- ...作为表达式的条件的值是表达式的值,对于除switch之外的语句,上下文转换为bool;
和(5.16条件运算符)
1条件表达式从右到左分组.第一个表达式在上下文中转换为bool(第4条).
因此,例如,如果上面的类具有使用函数说明符声明的以下转换运算符 explicit
explicit operator bool() const { return x != 0; }
Run Code Online (Sandbox Code Playgroud)
然而,它将被隐含地称为例如以下声明中
A a( 10 );
std::cout << ( a ? "true" : "false" ) << std::endl;
Run Code Online (Sandbox Code Playgroud)
这里a将在条件运算符中转换为bool类型的对象.
编辑:你更新了这个表达式后的问题
w1+1;
Run Code Online (Sandbox Code Playgroud)
与操作员完全匹配
wrapper operator+(int);
Run Code Online (Sandbox Code Playgroud)
无需转换.所以代码编译成功.