I have though about operator overloading and come with an interesting code:
#include <iostream>
class A {
public:
operator bool() {
return true;
}
bool operator!() {
return false;
}
};
int main() {
A a;
if (!a) {
std::cout << "HELLO";
} else {
std::cout << "WORLD";
}
std::cout << std::endl;
return 0;
}
What will be called first and what after? And why? Is this described anywhere in the cppreference?
P.S. For downvoters and others who think I could not execute this code by myself. I could. I did. I have changed it many times to see it's behavior. So what? This is not an explanation. I have asked for a reference which clearly states what rule this code obeys. The information how it works on my machine does not answer the question - what if this is not even portable across different environments (OSes, maybe processors, and so on)?
How it works is simple. The compiler parses the source and sees if(!a). It then checks if A defines an operator!. Just so happens that it does. So that gets called.
If it had seen if(a) it would have checked that an A is convertible to something which can be used in the condition of an if. Just so happens that it is indeed convertible.
If there had been no operator!, the compiler would have instead checked that an A can be converted to something which may be logically negated. Then the conversion to bool would have been performed.
BTW, the conversion will happen even in surprising places. For instance a + 1 will compile. Not what we want, I think. It's best to allow it only where a bool is contextually expected. You do that by marking the conversion operator explicit:
explicit operator bool() {
return true;
}
!a is no more than syntactic sugar for a.operator!(), which you have defined: that's the compiler's preferred choice.
So the conversion to bool operator is never a candidate.
You could contrive the latter by writing
if (!(bool)a) {
Related
I'm reading the code of ROS.
In the file ros_comm/roscpp/include/ros/subscriber.h, I see such a piece of code:
operator void*() const { return (impl_ && impl_->isValid()) ? (void*)1 : (void*)0; }
Well, (void *)0 can be regarded as NULL in C, but what does (void *)1 mean?
If a class Foo contains this function, it means that we can code like this:
Foo foo;
void *ptr = foo;
Right? So does it mean that void *ptr = (void *)1 is possible? What does this mean?
This is an old trick to avoid problems with implicit conversions to bool from before explicit contextual conversions were introduced in C++11. It's intended to be used to check validity:
Subscriber my_subscriber = someFunction();
if (!my_subscriber) {
// error case
}
The important point is that no built-in conversion exists from void* to integer types, but one does exist from bool to integer types. At the same time, a built-in conversion from void* to bool exists. That means that if you define an implicit conversion to bool, then the following is surprisingly valid:
void my_func(int i);
void another_func() {
Subscriber sub = something();
my_func(sub);
}
Defining a conversion to void* avoids that issue.
These days that trick is obsolete though. C++11 introduced explicit conversions. explicit conversions to bool are considered in the conditions of if and loops, but aren't considered in other problematic cases. That means that these days that conversion should be written as:
explicit operator bool() const { return impl_ && impl_->isValid(); }
It shows that either the person who wrote the code isn't very well acquainted with the language or tools they're using, or the code has been around for a long, long time and been hacked on by different people, presumably having undergone a C-to-C++ transition at some time in the past, still carrying some legacy API contract (expecting a void*) which may be troublesome to change.
There is no good reason to do such a thing, if you look at the source. impl_ is a boost::shared_ptr<Impl> which implements operator bool, and Impl::isValid returns bool, too. There's no reason to use, or return anything but bool anywhere.
Basically, this is a contorted (and possibly dangerous) way of writing:
return impl_ && impl_->isValid();
In my program, I would like to take the address of a temporary. Here is an example:
#include <iostream>
struct Number {
int value;
Number(int n) {
value = n;
}
};
void print(Number *number) {
std::cout << number->value << std::endl;
}
int main() {
Number example(123);
print(&example);
print(&Number(456)); // Is this safe and reliable?
}
This would output:
123
456
To compile, the -fpermissive flag is requied.
Here is my question: is this safe and reliable? In what possible case could something go wrong?
If your definition of "safe and reliable" includes "will compile and produce the same results if the compiler is updated" then your example is invalid.
Your example is ill-formed in all C++ standards.
This means, even if a compiler can be coerced to accept it now, there is no guarantee that a future update of your compiler will accept it or, if the compiler does accept the code, will produce the same desired effect.
Most compiler vendors have form for supporting non-standard features in compilers, and either removing or altering support of those features in later releases of the compiler.
Consider changing your function so it accepts a const Number & rather than a pointer. A const reference CAN be implicitly bound to a temporary without needing to bludgeon the compiler into submission (e.g. with command line options). A non-const reference cannot.
&Number(456) is an error because the built-in & operator cannot be applied to an rvalue. Since it is an error, it is neither safe nor reliable. "What could go wrong" is that the code could be rejected and/or behave unexpectedly by a compiler which follows the C++ Standard. You are relying on your compiler supporting some C++-like dialect in which this code is defined.
You can output the address of the temporary object in various ways. For example add a member function auto operator&() { return this; } . The overloaded operator& can be applied to prvalues of class type.
Another way would be to have a function that is like the opposite of move:
template<typename T>
T& make_lvalue(T&& n)
{
return n;
}
and then you can do print(&make_lvalue(Number(456)));
If you are feeling evil, you could make a global template overload of operator&.
This is fine but..
Number *a;
print(a); // this would be a null ptr error
How I would change it is
void print(const Number num) // make the paramater const so it doesnt change
{
std::cout << num.value << std::endl; // note the . instead of -> cuz this is a reference not a pointer
}
You would remove the "&" from your code like:
Number example(123);
print(example);
print(Number(456));
and if you need to pass a pointer you just put a "*" to dereference it.
chasester
Consider the following class, just as a simple example:
#include <iostream>
#include <string>
using namespace std;
class point {
public:
int _x{ 0 };
int _y{ 0 };
point() {}
point(int x, int y) : _x{ x }, _y{ y } {}
operator string() const
{ return '[' + to_string(_x) + ',' + to_string(_y) + ']'; }
friend ostream& operator<<(ostream& os, const point& p) {
// Which one? Why?
os << static_cast<string>(p); // Option 1
os << p.operator string(); // Option 2
return os;
}
};
Should one call a conversion operator directly, or rather just call static_cast and let that do the job?
Those two lines will pretty much do exactly the same thing (which is to call the conversion operator), there's no real difference between their behavior as far as I can tell. So the real question here is whether that's true or not. Even though these seem the same to me, there could still be subtle differences that one might fail to pick up on.
So are there any practical differences between those approaches (including ones that might not apply to this example), other than the fact that the syntax for them different? Which one should be preferred and why?
So are there any practical differences between those approaches
In this case, not that I know of, behaviour wise.
(including ones that might not apply to this example)
static_cast<X>(instance_of_Y) would also allow conversion if X has a converting constructor for the type Y. An explicit call to (possibly non-existent) conversion operator of Y could not use the mentioned converting constructor. In this case of course, std::string does not have a converting constructor for point.
So, the cast is more generic and that is what I would prefer in general. Also "convert this object to type string" is more meaningful than "call the operator string()". But if for some very strange reason you want to avoid the converting constructor, then explicit call to conversion operator would achieve that.
No you never need to call the conversion operator member function directly.
If you use an instance of the class where a std::string object is expected then the conversion operator will be called automatically by the compiler, as will it if you use e.g. static_cast to cast an instance to std::string.
Simple and stupid example:
void print_string(std::string const& s)
{
std::cout << s << '\n';
}
int main()
{
point p(1, 2);
print_string(p); // Will call the conversion operator
print_string(static_cast<std::string>(p)); // Will call the conversion operator too
}
The closest to call the function directly you will ever need is using something like static_cast.
In your specific case, with the output operator, then you should use static_cast. The reason is semantic and for future readers and maintainers (which might include yourself) of the code.
It will of course work to call the conversion member function directly (your option 2) but it loses the semantic information that says "here I'm converting the object to a string".
If the only use of the conversion operator is to use in the output operator, you might as well create a (private) function that takes the output stream reference as an argument, and writes directly to the stream, and call that function from the output operator.
Today I found a syntax thing I had never seen before. Are || and , the same?
bool f() {
cout << "f";
return true;
}
bool g() {
cout << "g";
return true;
}
int main() {
if(f(),g())
{
cout<<"OK with ,";
}
cout<<endl;
if(f()||g())
{
cout<<"OK with ||";
}
return 0;
}
From the output of this program, it seems so:
fgOK with ,
fOK with ||
Are they the same exact thing or are there any little differences?
f(),g() means evaluate f() then evaluate g() and return g() since your g() returns true it is that what is returned to if
So, no, the operators are totally different.
You can see the difference if you modify your function to return false from g(). The condition f()||g() will still evaluate to true while f(),g() will return false.
This (comma operator)
if(f(),g())
will evaluate both f() and g() and return the value of the second operand g()
The logical OR operator
if(f()||g())
will not evaluate g() if f() evaluates to true. This is known as short-circuit evaluation - if f() returns true, then the logical OR condition is already satisfied - hence there is no point evaluating g().
So they are NOT the same at all even though under certain conditions you may see the same overall behaviour.
|| is the logical OR operator and by standard it follows short-circuit evaluation (i.e. it won't evaluate the second operand if the first already suffices to determine the entire logical expression)
, is the comma operator that evaluates both but just return the value of the second operand.
By the way you should be seeing something like:
fgOK with ,
fOK with ||
the reason why you're not seeing it might be because you're using a compiler that doesn't strictly follow the standards (I suspect MSVC..)
http://ideone.com/8dSFiY
They are completely different operators that serve completely different purposes.
The main difference is that:
The , operator (unless overloaded) will evaluate all of its arguments and return the last one, no matter what.
The || operator will evaluate all the arguments until it reaches the first trueish value and will not evaluate the rest.
This is also the reason why the output, you are claiming to receive, is wrong.
I'm curious how the fstream class is able to return a true or false value by simply placing the name of the object inside a conditional statement. For example...
std::fstream fileStream;
fileStream.open("somefile.ext");
if (!fileStream) // How does this work?
std::cout << "File could not be opened...\n";
I ask this because I want my own class to return a value if I use it in a similar way.
It's not really that it is equal to true or false, but rather that it overloads the ! operator to return its status.
See http://www.cplusplus.com/reference/iostream/ios/operatornot/ for the details.
Doing this yourself is very simple, check out the operator overloading faq or C++ Operator Overloading Guidelines.
Edit:
It's been pointed out to me that ios also overloads the void * conversion operator, returning a null pointer in the case of a failure. So you could also use that approach, also covered in the previously mentioned faq.
This works using a conversion operator. Note that the seemingly obvious way, conversion to bool, has unintended side effects, therefore a conversion to a built-in type with implicit conversion to bool should be used, e.g.:
class X
{
public:
void some_function(); // this is some member function you have anyway
operator void(X::*)() const
{
if (condition)
return &X::some_function; // "true"
else
return 0; // "false"
}
};
In C++11, you can make the conversion to bool explicit, and thus avoid the unintended side effects. Thus in C++11 you can simply write:
class X
{
public:
explicit operator bool() const
{
return condition;
}
};