显式关键字 [英] explicit keyword

查看:64
本文介绍了显式关键字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对显式关键字有疑问.据我了解,explicit关键字可防止以下代码的发生.这使我感到困惑.原因是您在赋值运算符的左侧有一个类(指示某种形式的复制),而在右侧则有一个整数.因此我们无法进行成员明智的复制.因此,如果我们没有指定成员,那么我们希望复制的号码到底在哪里.我同意发生的事情是意料之外的.但我不明白为什么您会尝试以这种方式将数字传递给班级.

I have a question on the explicit keyword. It is my understanding that the explicit keyword prevents the following code below from happening. this confuses me. the reason is you have a class on the left hand side of a assignment operator (indicating some form of copying) then an integral value on the right. so we cant do a member wise copy. so where exactly do we expect that copied number to go if we specify no members. I do agree that what happens is unexpected. but i dont see why you would try and pass a number to a class in this way to start with.

class circle
{
public:
    circle(int size) : size(size){}

    void print() const
    {
        cout << size << endl;
    }

private:
    int size;
};

int main(int argc, char* argv[])
{
    circle circ = 42; // implicit conversion
    circ.print(); // prints 42
}

推荐答案

C ++编译器将尽最大努力满足您的愿望,有时您不希望将构造函数视为自动转换.

可以说,circle的构造函数采用File而不是int作为其参数,而File的构造函数采用int表示打开的文件句柄.

从文件创建圆时,它将尝试从文件中读取其定义,有点牵强,但我想您会感到困惑.

将File :: File(int handle)声明为显式有助于防止使用单参数构造函数自动转换的有趣副作用.

问候
Espen Harlinn
The C++ compiler will try it''s best to fullfill your wishes, and sometimes you don''t want a contructor to be considered for automatic conversion.

Lets say circle has a constructor taking a File, and not an int, as it''s argument, and File has a constructor taking an int representing an open file handle.

When circle is created from a File it will try to read its definition from the File, a bit farfetched, but I guess you get the drift.

declaring File::File( int handle ) as explicit helps to prevent funny side effects of automatic conversion using single argument constructors.

Regards
Espen Harlinn


explicit修补程序最常见的问题是调用函数时的自动转换.假设您有一个函数f,它使用您的circle对象之一:

void f( circle do_it_on_this );

大多数时候,您会使用完全构造的circle:
来称呼它
The most common problem that explicit patches is automatic conversions when you call functions. Say you have a function, f, that takes one of your circle objects:

void f( circle do_it_on_this );

Most of the time you''ll call it with a fully constructed circle:

circle c( 100 );
f( c );



但是,这也意味着像这样的调用:



However it also means that a call like:

f( 100 );



也可以.这可能会带来令人不快的副作用,使编写代码的程序员误以为f在没有f的情况下具有整数重载.在您的问题中,您似乎在问为什么在上帝的地球上,任何人都会设计一种编程语言,该语言首先允许这种形式的隐式转换.如果C ++没有隐式转换,则我们不需要explicit来禁用它.

发生这种情况的主要原因有两个.第一个是与从年份点开始编写的代码的兼容性.那里有大量的代码期望进行隐式转换(尤其是在C ++ 98编译器之前编写的东西).某些代码本不应该编写,但事后看来确实很容易讲.如果标准委员会扭转了这种行为(例如通过引入隐式关键字),那么那里有很多代码将停止工作并需要大量工作才能再次工作.

第二个问题是隐式转换在某些情况下实际上很有用.如果使用得当,它可以减少所需的重载数量,并有助于消除使Lisp程序员弄湿自己的嵌套语句.数值程序员非常喜欢这种事情,因为他们可以使用内置类型和滚动数值类型,并且通过使用转换构造函数,可以消除类操作中的一组重载.使用隐式转换,您不需要像下面这样乱扔代码:



will also work. This can have the unhappy side effect of confusing the programmer who wrote the code into thinking that f has an integer overload when it doesn''t. In your question you seem to be asking why on God''s earth anyone would design a programming language that allowed this form of implicit conversion in the first place. If C++ didn''t implicitly convert then we wouldn''t need explicit to disable it.

There are two main reasons this occurs. The first one is compatibility with code written since the year dot. There''s loads of code out there (especially stuff written before C++98 compilers were readily available) that were written expecting implicit conversion. Some of this code should never have been written but that''s really easy to say in hindsight. If the standards committee had reversed the behaviour (e.g. by introducing an implicit keyword) then there''s a lot of code out there that would stop working and need a significant amount of work to get working again.

The second one is that implicit conversion is actually useful in some cases. If used carefully it can reduce the amount of overloads you need and help get rid of nested statements that would make a Lisp programmer wet themselves. Numeric programmers like this sort of thing a lot as they can use built in types and handrolled numeric types and, by using a converting constructor, can eliminate one set of overloads from the operations on a class. With implicit conversion you don''t need to litter your code with things like:

f( big_int( 87 ) );



或必须编写转发功能,例如:



or have to write forwarding functions like:

void f( int n )
{
    f( big_int( n ) );
}



由于大多数人不了解选择重载和替代的规则,因此可以提高重载分辨率.

[另一个例子是使用字符串文字的传统,您应该在其中使用字符串,以便您可以编写如下内容:



which can gum up overload resolution as most people don''t understand the rules by which overloads and overrides are selected.

[Another example is the tradition of using string literals where you should be using strings so you can write things like:

f( "It''s all gone horribly wrong" );


代替:


instead of:

f( std::string( "It''s all gone horribly wrong" ) );



不必指定f的两个重载.]

无论如何,我希望这能使该功能(如果您不认为它是一个功能,但会发现一个错误,可以在单词周围加上引号).如果您有机会,请看Bjarne Stroustrup撰写的"C ++的设计和演进".它讨论了在标准化过程中必须保持工作状态的人员之一的观点,这些问题必须围绕explicit进行考虑.

干杯,



without having to specify two overloads of f.]

Anyway, I hope this lot puts the feature (feel free to add quotes around the word if you don''t think it''s a feature but a bug that''s hung around) in context. If you get a chance have a look at "The Design and Evolution of C++" by Bjarne Stroustrup. It discusses some of the design issues that had to be considered around explicit from the point of view of one of the people that had to keep things working during standardisation.

Cheers,

Ash


这篇关于显式关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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