类类型之间的隐式转换 [英] implicit conversions from and to class types

查看:97
本文介绍了类类型之间的隐式转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究C ++中的转换构造函数和转换运算符。
到目前为止,我了解到的是,仅采用一个参数(以及任意数量的可选默认参数)的任何非显式构造函数都表示将隐式类类型转换为THAT类类型,例如,如果一个类定义了一个具有类型为 int 的参数的构造函数,我可以在需要该类类型的对象的任何地方使用 int

I am studying converting constructors and conversion operators in C++. What I've learned so far is that any non-explicit constructor that takes only one parameter (and any number of optional default arguments) represents an implicit class-type conversion to THAT class type, for example if a class defines a constructor that has one parameter of type int I can use an int wherever an object of that class type is required:

(假设class_type重载了+ =运算符)

(assuming class_type has an overloaded += operator)

class_type a;
a+=5;

在这种情况下,5被隐式转换(通过转换构造函数)为 class_type 并调用了重载运算符。

in this case 5 is implicitly converted (through the converting constructor) to class_typeand the overloaded operator is called.

现在,(至少对我来说)棘手的部分:我知道我可以将转换运算符定义为成员函数:

Now, the (at least for me) tricky part: I know I can define a conversion operator as a member function :

operator int() {....};

class_type 的对象转换为基本的 int 类型,我可以使用这种转换方式:

that converts the object of class_type to the primitive int type, and I can use that conversion like:

class_type a;
a+5;

在这种情况下,我读到对象是通过其转换运算符转换为int的,然后内置总和运算符被调用。
但是,如果我定义了一个重载+运算符来接受两个class_type对象作为其参数,该怎么办?类似于

in this case I've read that the object is converted to an int through its conversion operator and then the buil-in sum operator is called. But what if I defined an overloaded + operator to take two class_type objects as its arguments? something like

class_type运算符+(const class_type&,const class_type& c);

编译器应该如何通过函数匹配知道要调用哪个?
仅在定义了内置运算符时,隐式发生向 int 的转换吗?

how is the compiler supposed to know which one to call through function matching? does the conversion to int only happens implicitly when only the built-in operator is defined?

谢谢!

编辑:

实际上,我试图编写一些代码来有效地进行尝试,原来我的编译器(g ++)不会发出任何模棱两可的调用错误!

actually,I've tried to write some code to effectively try it out, it turned out that my compiler (g++) doesn't issue any ambiguous call error!

这是类标头(以及非成员operator +函数声明):

this is the class header (along with the non-memeber operator+ function declaration) :

#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&);

这是主要代码:

#include "wrapper.h"

int main()
{
  using namespace std;
  wrapper w1;
  wrapper w2(5);
  cout<<w1<<" "<<w2<<endl;
  w1+1;  
}

现在,我从定义了一个转换构造函数int wrapper 以及从类类型到 int 的转换运算符(我也重载了<<<<<<<>输出运算符以打印一些结果),但是当编译器评估表达式 w1 + 1 时似乎不错。

now,I've defined a converting constructor from int to wrapper AND a conversion operator from class type to int(I've also overloaded the << output operator in order to print some results), but when the compiler evaluates the expression w1+1 it seems to be fine. How could it possibly be??

推荐答案

例如,如果您有以下包含转换构造函数和转换运算符的类声明,

If you have for example the following class declaration that contains a conversion constructor and a conversion operator

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 );
}

然后声明

a1 + a2;

其中a1和a2的声明例如

where a1 and a2 are declared like for example

A a1( 10 );
A a2( 20 );

格式正确,因为不需要调用转换函数。这两个操作数都与运算符+的参数声明匹配。

will be well-formed because there is no need to call a conversion function. The both operands match the parameter declarations of the operator +.

但是,如果您要编写示例,例如

However if you will write for example

a1 + 20;

当编译器由于存在歧义而发出错误时。编译器可以应用转换构造函数 A(int)将第二个操作数转换为类型 A 并调用定义的运算符对于 A 类型的对象。也可以应用转换运算符 operator int 将第一个操作数转换为类型 int 并调用内置的 operator + 用于类型 int 的对象。

when the compiler issues an error because there is an ambiguity. The compiler can either apply conversion constructor A( int ) to convert the second operand to type A and call the operator defined for objects of type A. Or it can apply the conversion operator operator int to convert the first operand to type int and call the built-in operator + for objects of type int.

避免这种歧义性可以用函数说明符 explicit 声明构造函数或运算符(或两者)。

To avoid this ambiguity you could declare either the constructor or the operator (or the both) with function specifier explicit.

例如

    explicit A( int x ) : x( x ) {}

    explicit operator int() const { return x; }

在这种情况下,将仅存在一个隐式转换,并且没有歧义。

In this case only one implicit conversion would exist and there was not an ambigiuty.

我想附加上面的描述,有时即使使用函数说明符 explicit 。

I would like to append the above description that sometimes some converion operators can be called implicitly even if they are declared with the function specifier explicit.

例如,根据C ++标准(6.4选择语句)

For example According to the C++ Standard (6.4 Selection statements)



  1. ...作为表达式的条件的值就是
    表达式的值,对于
    而不是switch的语句,上下文转换为bool;


和(5.16条件运算符)

and (5.16 Conditional operator)

1条件表达式组从右到左。第一个表达式是
在上下文中转换为bool(第4条)。

1 Conditional expressions group right-to-left. The first expression is contextually converted to bool (Clause 4).

例如,如果上述类具有以下内容使用函数说明符 explicit

So for example if the above class has the following conversion operator declared with the function specifier explicit

explicit operator bool() const { return x != 0; }

不过,例如,在以下语句中将隐式调用它

nevertheless it will be called implicitly for example in the following statement

A a( 10 );

std::cout << ( a ? "true" : "false" ) << std::endl;

在条件运算符中,a将被转换为bool类型的对象。

Here a will be converted to an object of type bool in the conditional operator.

编辑:更新问题后该表达式

After you updated your question this expression

w1+1; 

与运营商完全匹配

wrapper operator+(int);

都不需要转换。这样代码就可以成功编译。

Neither conversion are required. So the code compiles successfully.

这篇关于类类型之间的隐式转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆