Click here to Skip to main content
15,867,488 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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
}
Posted

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
 
Share this answer
 
Comments
malifer 30-Jan-11 17:11pm    
Thanks I appreciate that you took the time to answer. someone else on a different forum mentioned the string class. so from another view why you would want this conversion to happen.
Espen Harlinn 30-Jan-11 17:21pm    
Let us say you are implementing a geometry library that only uses doubles internally - automatic conversion from POINTL to MyLib::Point using MyLib::Point::Point(const POINTL& pointl) is probably a candidate.
Sergey Alexandrovich Kryukov 30-Jan-11 18:52pm    
Good motivation, a 5.
--SA
JF2015 1-Feb-11 8:29am    
Good addition to the other answer. 5
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 );


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


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
 
Share this answer
 
v3
Comments
Espen Harlinn 30-Jan-11 17:39pm    
Thorough good work, an obvious 5+
Sergey Alexandrovich Kryukov 30-Jan-11 18:53pm    
Agree - a 5.
--SA
malifer 30-Jan-11 19:33pm    
Thanks Ash. great explaination
JF2015 1-Feb-11 8:29am    
Good answer. 5!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900