Why C++ 11 added operator bool to the ios classes - c++

In C++ 98, there is a public function in ios classes defined as
operator void*() const;
An operator bool is added in C++11 to the class, that is
explicit operator bool() const;
From reading the reference, it is not clear to me why the operator bool is necessary.
Can anyone gives an example where operator void* causes problems, while operator bool works just fine?

In C++98 there were no explicit cast operators so if you had an operator bool it meant that the object could be used as a bool or anything that can be cast from bool (such as int) this meant that you could accidentally use your objects in ways that you wouldn't expect or want (such as obj + 2). Some objects provided a cast to void* which meant that the object could be tested in an if statement (not null) but would not be passable to functions expecting int etc.
With the introduction of explicit cast operators this is no longer needed and in order to have a testable object it's much better to use explicit operator bool than operator void*.

A void* is still not a perfect replacement to the shortcomings of an implicit conversion to bool. It suffers from the same problem as the conversion to bool did, chiefly that some operators allow classes to convert into a pointer before applying the operation.
One glorious example is that with void* operator, you could do something like delete std::cin;, and it will probably build without a warning, only to cause a failure at run-time. That's probably not code that's likely to be written, but it's still desirable to prevent it if at all possible.

It boils down to convenience and even a bit of "sponsorship" of new features from the library classes.
The void* conversion is dangerous because it can potentially be applied everywhere. Ok, in practice, since it's a pointer and you are probably going to use it in numeric espressions (mainly in conditions) it is kind of safe, but there is potential for trouble if someone try to use it anywhere else. As a class designer, you want to avoid it as much as possible.
In C++11, when you define explicit operator, you should keep in mind that, for what concerns us, the explicit part is ignored in a condition. So you are greatly narrowing the potential for unwanted conversions and then unwanted results. Outside of a condition, there will be no conversion and so a compile time error will warn you of a potential misuse of the class (that you can still willingly allow with proper cast).

Related

Why user-defined conversions are limited?

In C++, only one user-defined conversion is allowed in implicit conversion sequence. Are there any practical reasons (from language user point of view) for that limit?
Allowing only one user defined conversion limits the search scope when attempting to match the source and destination types. Only those two types need to be checked to determine whether they are convertible (non-user defined conversions aside).
Not having that limit might cause ambiguity in some cases and it might even require testing infinite conversion paths in others. Since the standard cannot require to do something unless it is impossible to do in your particular case, the simple rule is only one conversion.
Consider as a convoluted example:
template <typename T>
struct A {
operator A<A<T>> () const; // A<int> --> A<A<int>>
};
int x = A<int>();
Now, there can potentially be a specialization for A<A<A<....A<int>...>>> that might have a conversion to int, so the compiler would have to recursively instantiate infinite versions of A and check whether each one of them is convertible to int.
Conversely, with two types that are convertible from-to any other type, it would cause other issues:
struct A {
template <typename T>
A(T);
};
struct B {
template <typename T>
operator T() const;
};
struct C {
C(A);
operator B() const;
};
If multiple user-defined conversions where allowed, any type T can be converted to any type U by means of the conversion path: T -> A -> C -> B -> U. Just managing the search space would be a hard task for the compiler, and it would most probably cause confusion on the users.
IMHO It is a design choice based on the fact that constructors are not explicit by default. Which is a practical reason for setting a limit, to disallow the following expression to be valid.
objectn o = 5;
5-> object1(5)->object2(object1)->object3(object2)->...->objectn(objectn-1)
Each arrow above is an implicit conversion. One seems to be a reasonable choice.If more are allowed, you have several implicit conversion paths between an object0 and objectn . Each one leading to possibly different objectn o. Which one to choose??
If the allowed number were infinite, you could quite quickly end up with an attempted circular conversion sequence.
It's much easier to say "if you need more than one conversion, you have a design flaw" and use that rationale to emplace a bug-saving limit within the language.
In any case, implicit conversions are generally considered to be best when used sporadically. One conversion is very useful for the sort of heavy operator overloading used by the standard library, and similar code; beyond that, there's not much excuse to ever use implicit conversions. Certainly a language would go in the direction of seeking fewer, not more (e.g. C++11 adding explicit in this context, to help you enforce no implicit conversions at all).
If it allows more than one, then how many in the sequence? If infinite, then wouldn't it make too complicated for a large number of types in a large project? For example, everytime you add implicit conversion, you have to think really really hard as to what else it converts into and then what else that converts into? and the chain goes on. Very dangerous situation, IMHO.
Implicit conversions (what is currently allowed by the language) are considered bad, which is why C++11 has added contextual conversion which is implemented using explicit keyword.

Question on predefined meanings for operators

In "The C++ programming language", at page 265, the author makes the following statement:
Because of historical accident, the operators = (assignment), & (address-of), and , (sequencing;
§6.2.2) have predefined meanings when applied to class objects. These predefined meanings can
be made inaccessible to general users by making them private:
Then the following example is given:
class X {
private:
void operator=(const X&);
void operator&();
void operator,(const X&);
// ...
};
void f(X a, X b)
{
a = b; // error: operator= private
&a; // error: operator& private
a,b; // error: operator, private
}
I can't quite understand what do these "error" comments refer to? Does that mean I should not define a function like f, or that all of the =, &, and , operators should be used according to the default way, and it is not necessary to redefine them?
This example simply shows a way to prevent yourself or other developers of the code from using operators, which can be used without having been defined in the class, because they're automatically generated (and have default meanings for the operations they represent).
The author of the example meant, that if you try to assign b to a (in line a = b) it will cause an error, because the assignment operator is private in the class definition.
Similar error occurs in case of address-of in the second line, and the comma operator in the third.
Making default operators/constructors private if you know they're not supposed to be used (or haven't been implemented yet) is good, because one may accidentally use a very frequent operator like assignment or copy-constructor, being unaware that it's default behavior conflicts with the class lifecycle. If such operator or constructor is made private at the very beginning of class design, the compiler will generate a compile-time error instead of performing a potentially dangerous operation without notice if the programmer accidentally uses the method.
Think default assignment operator and member pointer: it will copy the pointer whereas you might want the object to be the owner of data. Then, after someone assigns one object to another without knowing that assignment is not implemented, you will end up with a double free error. Instead of that, if the operator is private, you'll get a nice error and the code will not even compile, and you'll know what's going on.
The author intends to point out here that the operators =, & and , are usually implicitly available for a class.
So if you don't want your objects to be operated on through them then you declare them as private thus disallowing their use.
Since they are declared as private you cannot access them anymore outside the class and the compiler gives you a compilation error. The function is an example showing that.
Providing your own implementation of any operator is basically the same as implementing a class method. Operators and methods are the same in terms of accessibility. What you do is disallowing access to operators from the caller's code.
It's absolutely the same as if you defined a private method and then tried to call it from some code that is not part of your class. Just make the operators public and errors will go away.
It basically prevents any one from making an 'X' object and using the "=", "&", and "," operators on that class. Because the author of the class may implement those objects with a meaning that is quite different to what the consumer of the class might think they do ... so its best to prevent them being used at all in the case of ambiguity.
The function f is an example of a user trying to use the private operators. It shows you what code it is that you're preventing by making them private. The comment // error means that a program that contained that line would fail to compile for the stated reason.
Before discussing the error, a key here is to understand that these operations will be implicitly made available for your class. This is the essence of Scott Meyers' advice "Know what functions C++ silently writes and calls."
C++ will automatically implement the assignment operator for your class, but it may not be done correctly (for example, if your class contains a pointer member variable). By defining the assignment operator explicitly, you are telling the compiler to use your implementation instead of generating one for you. And by making it private, you are essentially disallowing assignment of one class instance to another. Anywhere you try to do this in your code, the compiler will complain, which is a good thing if you really don't want assignment to be done.
In function f the author is showing you that these statements will not compile because of how the operators are defined in the class. It is perfectly acceptable to redefine operators for your class, and sometimes it is definitely required (for example, to implement a deep copy of a pointer member variable in your class). The point of the example is to show that a) you can provide your own implementation of these operators for your class, and b) because of this you have control over whether the operators are supported and implemented correctly for your class.

Macros to disallow class copy and assignment. Google -vs- Qt

To disallow copying or assigning a class it's common practice to make the copy constructor
and assignment operator private. Both Google and Qt have macros to make this easy and visible.
These macros are:
Google:
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
Qt:
#define Q_DISABLE_COPY(Class) \
Class(const Class &); \
Class &operator=(const Class &);
Questions:
Why are the signatures of the two assignment operators different? It seems like the Qt version is correct.
What is the practical difference between the two?
It doesn't matter. The return type is not part of a function's signature, as it does not participate in overload resolution. So when you attempt to perform an assignment, both declarations will match, regardless of whether you use the return type.
And since the entire point in these macros is that the functions will never get called, it doesn't matter that one returns void.
I'd just like to mention that there is an alternative strategy for implementing an abstraction for disallowing copy and assignment of a class. The idea is to use inheritance instead of the preprocessor. I personally prefer this approach as I follow the rule of thumb that it is best to avoid using the preprocessor when at all possible.
boost::noncopyable is an example implementation. It is used as follows:
class A : noncopyable
{
...
};
See Boost.Utility, specifically boost::noncopyable. It's not a macro but a base class with private copy and assignment. It prevents the compiler from generating implicit copy and assignment in derived classes.
edit: Sorry, this was not an answer to the original question. By the way, boost::noncopyable uses a const reference as return type for the assignment operator. I was under the impression that the type of the return value doesn't matter since it's not supposed to be used. Still, making the operator private doesn't prevent usage inside the class or friends in which case a non-usual return type (like void, a const reference, etc) might lead to compilation errors and catch additional bugs.
There's no practical difference. The assignment operator signatures differ just as a matter of style. It's usual to have an assignment operator returning a reference to allow chaining:
a = b = c;
but a version returning void is also legal and will work just fine for cases when the only purpose is to just declare the operator private and therefore prohibited to use.
From the standard, 12.8, clause 9: "A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X&, or const volatile X&." It says nothing about the return type, so any return type is permissible.
Clause 10 says "If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly."
Therefore, declaring any X::operator=(const X&) (or any other of the specified assignment types) is sufficient. Neither the body nor the return type is significant if the operator will never be used.
Therefore, it's a stylistic difference, with one macro doing what we'd likely expect and one saving a few characters and doing the job in a way that's likely to surprise some people. I think the Qt macro is better stylistically. Since we're talking macro, we're not talking about the programmer having to type anything extra, and failing to surprise people is a good thing in a language construct.
Others have already answered why it's legal to have different return values for operator=; IMHO jalf said it best.
However, you might wonder why Google uses a different return type, and I suspect it's this:
You don't have to repeat the type name when disabling the assignment operator like this. Usually the type name is the longest part of the declaration.
Of course, this reason is void given that a macro is used but still - old habits die hard. :-)
Both serve the same purpose
Once you write this one:
Class &operator=(const Class &);
you will get the benefits of chain assignments. But in this case you want the assignment operator to be private. so it doesn't matter.
Qt version is backward compatible, while google's is not.
If you develop your library and deprecate the use of assignment before you completely remove it, in Qt it will most likely retain the signature it originally had. In this case older application will continue to run with new version of library (however, they won't compile with the newer version).
Google's macro doesn't have such a property.
As several other answers have mentioned, the return type of the function doesn't participate in the function signature, so both declarations are equivalent as far as making the assignment operator unusable by clients of the class.
Personally I prefer the idiom of having a class privately inherit from an empty non-copyable base class (like boost::noncopyable, but I have my own so I can use it in projects that don't have boost available). The empty base class optimization takes care of making sure there's zero overhead, and it's simple, readable, and doesn't rely on the dreaded preprocessor macro functionality.
It also has the advantage that copy and assignment can't even be used within class implementation code - it'll fail at compile time while these macros will fail at link time (likely with a less informative error message).
Incidentally, if you have access to the Boost libraries (You don't? Why the heck not??), The Utility library has had the noncopyable class for a long time:
class YourNonCopyableClass : boost::noncopyable {
Clearer IMHO.
In practice I would say that both should not be used anymore if you have a C++11 compiler.
You should instead use the delete feature , see here
Meaning of = delete after function declaration
and here
http://www.stroustrup.com/C++11FAQ.html#default
Why : essentially because compiler message is much more clearer. When the compiler need one of the copy or copy assignment operator, it immediately points out to the line where the =delete was coded.
Better and complete explanations can also be found in Item 11: Prefer deleted functions to private undefined ones from Effective Modern C++ book by Scott Meyers

conversion operator as standalone function

Why does C++ require that user-defined conversion operator can only be non-static member?
Why is it not allowed to use standalone functions as for other unary operators?
Something like this:
operator bool (const std::string& s) { return !s.empty(); }
The one reason I can think of is to prevent implicit conversions being applied to the thing being cast. In your example, if you said:
bool( "foo" );
then "foo" would be implicitly converted to a string, which would then have the explicit bool conversion you provided applied to it.
This is not possible if the bool operator is a member function, as implicit conversions are not applied to *this. This greatly reduces the possibilities for ambiguity - ambiguities normally being seen as a "bad thing".
By keeping the conversion operator within the class you give the author of the class control of how it could be converted (It prevents users from creating implicit conversions). As an implementer I would consider this an advantage, as implicit conversions does have its issues
There is a difference being able to pass one object as another, and having it to go through a conversion function. The former communicates that the object is of a given type, while the latter shows new readers that there is a difference between the two types and that a conversion is necessary.
Implicit user-defined conversions are frowned upon anyway. Don't use them. Just pretend that they aren't there. Let alone thinking about newer ways to introduce them.
Anyway, I guess they aren't there because the way they are they can do enough unexpected things. Including a new header which introduces such a conversion for a class defined somewhere else might lead to even more confusing errors.
There's a group of operators that have to be overloaded as non-static member functions: assignment, subscripting, function call, class member access, conversion functions.
I guess the standard's committee or Stroustrup simply felt it might be just too confusing if it was allowed to inject these very special behaviors to classes from outside.
I suppose the best way to get the answer would be to e-mail the author.

An operator == whose parameters are non-const references

I this post, I've seen this:
class MonitorObjectString: public MonitorObject {
// some other declarations
friend inline bool operator==(/*const*/ MonitorObjectString& lhs,
/*const*/ MonitorObjectString& rhs)
{ return lhs.fVal==rhs.fVal; }
}
Before we can continue, THIS IS VERY IMPORTANT:
I am not questioning anyone's ability to code.
I am just wondering why someone would need non-const references in a comparison.
The poster of that question did not write that code.
This was just in case. This is important too:
I added both /*const*/s and reformatted the code.
Now, we get back to the topic:
I can't think of a sane use of the equality operator that lets you modify its by-ref arguments. Do you?
Perhaps the classes use a form of lazy initialization. When the data is accessed, proper initialization must occur, and the data must be fetched. This may change class members.
However, lazy initialization can be formed so that modification to the class isn't necessary. This can be accomplished by using the Pimpl idiom (by a pointer to a private class) or by using the mutable keyword (not recommended!).
Most likely they forgot the const.
Operator overloads should behave consistently and not perform 'out of character' actions.
As a general rule, an equality operator should never modify any of the objects it is comparing. Declaring const enforces this at the compiler level. However, it is often left out. "Const correctness" is very often overlooked in C++.
There's a more baffling problem with the issue you bring up.
If I have two MonitorObjectStrings that are already const, I can't use this equality function.
There's clearly no requirement for non-const args in this case and, like you, I wouldn't think there's any general case for it either.
However, it's certainly the case that const-correctness problems can push their way up from lower levels of the code, and if you can't correct them low-down, then you might have to work around them higher up. Perhaps that's what happened here at some point?
If you can't use const because you're modifying operands, you're badly misusing operator overloading.
If you can't use const because the implementation calls non-const functions, you really should clean those up, or at least provide const alternatives.
If you're calling into code you can't change which doesn't use const, I'd use the const anyway, use const_cast at the deepest available point, and comment it.
As Shmoopty pointed out, the operator is a lot less useful than it should be since it can't be used on const objects, even if only one of them is const. A numeric equality operator that wouldn't support "a == 5" would violate the Law of Least Astonishment in a big way.