Ternary operator and function signature - c++

Let's say I have a C++ class with two functions like
class MyClass
{
bool Foo(int val);
bool Foo(string val);
}
Is it possible to use the ternary operator like this
MyClassInstance->Foo(booleanValue?24:"a string");
and have a different function of MyClass invoked depending on the value of booleanValue?

Not with the ternary operator. The type of a ternary expression is the common type of its second and third operands; if they have no common type you can't use it. So just use an ordinary if statement:
if (booleanValue)
MyClassInstance->Foo(24);
else
MyClassInstance->Foo("a string");

The type of a ternary conditional expression is the common type two which both operands are con­ver­tible. You can definitely not perform "dynamic overload resolution", as you seem to be suggesting.
Since there is no common type for int and char const *, the code won't even compile (as you sure­ly noticed when you tested this).
(You may be thrilled to know that the ternary conditional is used precisely because of those semantics in the implementation of the std::common_type trait class template, together with decltype.)
(If the condition is known statically, such as sizeof(int) != 7, then you can use template spe­cia­lization to write similar-looking code that does perform conditional overload resolution, but of course statically.)

No. To perform overload resolution the compiler will ask "what is the type of booleanValue?24:"a string"?". That question cannot be answered.

No, this is not permitted.
Overloads are compile-time, so it cannot work in runtime that way.
It is not common in code you would want to do exactly that, however sometimes with iostream there is a desire to do something like:
os << ( condition ? var1 : var2 )
where var1 and var2 have different types. That also doesn't work.
You could do:
MyClassInstance->Foo( booleanValue ? boost::any(24) : boost::any("a string") );

Related

How to use ternary operator just as if statement?

I want to use ternary operator("? : ") as if statement statement.To be precise I want to do something like this,if(temp>0) so increment 'i' else do nothing.
temp?i++:WHAT_SHOULD_COME_HERE_SO_NO_CHANGES_ARE_MADE_ANYWHERE
Answer
Strictly speaking, you can't do this:
(boolean expression) ? (returning expression) : /* no-op */;
Something has to go in the third operand. However, you can make that "something" behaviorally equivalent to a no-op in terms of the post-conditions of evaluating the ternary operator. See below.
Explanation
The ternary operator must return a value, and the type is deduced as the most derived type that is a supertype of the return type of each of the second and third operands. So if the third operand is a blank expression (i.e. it returns nothing), then the compiler cannot deduce a return type for the operator as a whole. Thus, it will not compile.
Solution
Using the ternary operator:
If you really wanted to, this is how you might do it using the ternary operator:
i = temp>0 ? i+1 : i;
or
temp>0 ? ++i : i;
Preferred syntax:
Although if all you're looking for is a one-liner, then the following syntax is preferred:
if (temp>0) ++i;
This will work:
(void) ((temp>0)?i++:0);
Note that the (void) does not change the behavior of the code; rather it is there to indicate to the reader (and/or any style checking programs you might invoke in the future) that the result of the expression is being deliberately discarded. Without it you may get warnings from the compiler and/or other programmers suspecting a bug and trying to "fix" your code.
Actually, you may get that anyway, since the above is a very unusual way to express what you are trying to do. The code will be easier for others to understand and maintain if you instead use the traditional form:
if (temp>0) i++;
The ternary operator is used in an expression. As such, the entire expression must evaluate to a single value. This means that you must supply both the "if" and "else" clauses. There is no way to leave the "else" part blank.
In addition, embedding an increment operator within an expression such as this is inadvisable since the consequences of the side-effect are so error-prone.
you can:
int temp = 20, i = 0;
(temp)? i++: i;
cout << i << endl;

Write an oveloaded comparison (==) between two primative types, in C++

As pointed out by this article, it is impossible to overload the comparison operator (==) such that both sides could take primitive types.
"No, the C++ language requires that your operator overloads take at least one operand of a "class type" or enumeration type. The C++ language will not let you define an operator all of whose operands / parameters are of primitive types." (parashift)
I was wondering:
**If I really-really needed to compare two primitives in a non-standard way using the ==, is there a way to implicitly cast them to some other class?
For example, the following code will work for const char* comparison, but it requires an explicit cast. I would prefer to avoid explicit casts if possible.
// With an explicit cast
if(string("a")=="A") // True
// Without the cast
if("a"=="A") // False
// An example overloaded function:
bool operator == (string a, const char* b)
{
// Compares ignoring case
}
Casting can be pretty clunky in some situations, especially if you need to do several casts inside a long expression. So that's why I was looking for a way to automatically cast the first input (or both) to a sting type.
Edit 1:
Another way to do this is to write an isEqual(const char* a, const char* b) function, but I want to avoid this because it will result in a mess of parenthesis if I were to use it inside of a large if-statement. Here's an oversimplified example that still shows what I mean:
if (str1 == str2 || str1 == str3 || str2==str4)
As opposed to:
if (isEqual(str1,str2) || isEqual(str1,str3) || isEqual(str2,str4))
Edit 2:
I know there exist many ways to achieve the desired functionality without overloading the ==. But I looking specifically for a way to make the == work because I then could apply the knowledge to other operators as well.
This question is in fact closely related to the Wacky Math Calculator question I asked a few weeks ago, and being able to overload the == will help make the code look considerably nicer (visually, but perhaps not in a "clean code" way).
And that's I wanted to ask this question here on SO, in case someone had a cool C++ trick up their sleeve that I didn't know about. But if the answer is No then that's fine too.
You could certainly write one or more free functions to do your comparison. It doesn't have to be an operator overload.
for example:
bool IsEqual(const char* a, const string& b)
{
// code
}
bool IsEqual(const string& a, const char* b)
{
// code
}
and so on.
If the types of the operands are given, and you cannot add an overload for equality, because
It is simply not overloadable, because all are primitive types
There is already an overload, which does not do what you want
You do not want to risk violation of the ODR because someone else could be pulling the same kind of stunts you do (In which case a TU-local override might work, aka free file-local. Be aware of adverse effects on templates.)
there are just two options:
Use a wrapper and overload all the operators to your hearts content.
Use a function having the desired behavior explicitly and just forget about the syntax-sugar.
BTW: That standard-library containers and algorithms often can be customized three ways:
Using a type having overloaded operators
Having the used standard traits-class specialized
Providing a different traits-class.
No, there's no way to implicitly cast the primitive types the way you want.
The only way to achieve the desired functionality is either by explicitly casting the inputs into another class as stated in the question, or by creating a free function as shown by #Logicat.

Combined Operator Overloading in C++?

Is it possible to overload operators in such a way that you can capture a specific combination of them? For example lets say I have a custom object myObject of type MyType where [] is already overloaded to pass such calls down to a map object. That said, in the case of the following code:
int value = myObject["someProp"];
I'm already overloading [] but in this case I'd like to know when [] is being called on the object in an assignment, with a reference to the type of object that the property lookup is to be assigned to. This way I can cast the value coming out of the dynamic property lookup and so on and so forth. Any input is appreciated!
For more insight into exactly what I'm trying to accomplish, see this related question of mine.
No, you can't overload on the return type, or on the context in which the call appears (e.g. in an assignment etc).
You could, however, return a proxy object that would have a bunch of overloaded conversion operators. Without seeing what you intend to do, it's hard to say how far you might be able to get with this approach, or whether it's even a sane thing to do.
If you want type deduction for things like this, your best bet is to overload operator() instead, and pass in the thing you're going to be assigning to as a dummy parameter, i.e.:
MyType myObject;
int value = myObject("someProp", value);
I've made something like this work pretty well in the past. In particular, see e.g.:
https://github.com/sgolodetz/hesperus2/blob/master/source/engine/core/hesp/objects/base/ObjectManager.tpp
In principle, it's rather straightforward to do: all that is needed is
for your operator to return a proxy which then overloads the operators
you want to catch. In practice, it can cause more than a few problems;
readers will expect (a op1 b) op2 c to have
the same semantics as T tmp(a ip1 b); tmp op2
c. There are some common exceptions, however:
The operator[] in a multi-dimensional array will often return a
proxy which defines an operator[] itself, in order to support [][]
correctly.
More generally, a container which for whatever reasons needs to know
when a value is modified will have an operator[] which returns a
proxy; within the proxy, assignment is defined as setting the value in
the owning container, and there will be a convertion operator to the
value type, for use in rvalue contexts. Of course, this means that
things like m[i][j].funct() don't work; typically, however, this sort
of thing is used for matrices of numeric types, where member functions
aren't that relevant.
In contexts where it is desirable to support overload resolution based
on the target type (your example), the function can return a proxy with
overloaded conversion operators. You want to be extremely careful with
this—overloaded conversion operators are often a recipe for
overload resolution ambiguities&rdash;but there are enough exceptions
that this situation bears mentionning. (Important, here, is that the
results of the operator will amost always be used to intialize or to
assign to a specific object, the type of which determines which
conversion operator will be called.)
BTW: I might mention that in the example you give, there is no
assignment; it is a classical initialization. In this case, defining
the operator[] to return a proxy which defines operator int() const
would do the trick very well. Before going this route, however, you
should very definitely consider all of the use cases of your class, and
ensure that there are none in which the actual target type is ambiguous.
The other answers are basically correct that you can't do it. aix hints at a solution of a custom return type with overloaded conversion operators, but rightly indicates it isn't a sane thing to do. I've ventured down this path quite often and ultimately implicit conversions, and sequences of conversions, and ambiguities will bite you in you in the behind.
I've had a need of this quite often though. Ultimately I end up going for a series of overloaded functions, or templates, depending on your needs, perhaps like this:
void lookup( int& v, char const * name );
void lookup( double& c, char const * name );
In the template case I created global converters and did the below member function:
template<T>
void lookup( T&v, char const* name ) { v = convert<T>( get(name) ); }
If you want to keep the return value as the lookup you'll have to explicitly call a templated function.
template<T> T get( char const * name ) { ... }
//use
int a = obj.get<int>( "name" );
double b = obj.get<double>( "floaty" );
No, you can't do that.
Moreso, madness that way lies!

Difference between operator and function in C++?

I could use some help understanding the following in C++, particularly the difference between an operator and a function:
What is an operator?
What is a function?
What is the difference between them?
Is a user-defined operator+() a function or an operator?
Can an operator operate on operands at compile-time? Do they always operate at compile time? (like sizeof() in C++)
An operator is a symbol like +, -, += and so forth (see 13.5). They don't carry a meaning. During semantic analysis, the meaning of an operator is determined.
A function is a constructor, destructor, conversion function (that looks like operator type()) or operator function (function template specialization and instantiation can yield these in turn).
An operator function is something that implements an operator (see 13.5). An example is operator+. These are functions in all respects, and the only difference to "usual" functions is that they may be called implicitly and they have a funny name.
Some operators have a built-in meaning, that can be changed by the programmer. One refers to the built-in meaning of an operator simply by saying built-in operator (see 5/3). However, if such an operator is applied on operands for which a built-in meaning is defined, changing that meaning is only allowed for a few cases (these are assignment, address-of and the comma operator, see 13.5/6).
What is an operator?
An operator is a symbol that is use in expressions.
Examples are: + - * / etc
On built-in types there operations are well defined and unchangable.
For user defined types the operators can be defined as syntactic sugar for a function/method call
Array a;
a = b + c; // a.operator=(b.operator+(c));
What is a function?
We use the term function/method interchangeably most of the time. The only difference is that a method is associated with an instance of a class object. Otherwise they are the same. They provide a way of grouping a set of instructions together.
What is the difference between them?
The action of an operator on a built-in type is defined by the compiler.
The action of an operator on a user defined type is a function call.
Is a user-defined operator+() a function or an operator?
Its a function (or a method). Use of an operator on a user defined type is syntactic sugar for a function call. They are still refereed to as operators though in normal conversation.
Can an operator operate on operands at compile-time?
For built-in types yes. The compiler has extensive ability to optimize there usage.
For user defined types. It can perform optimizations on the operators just like other functions which may lead to there being eliminated, but the code is not executed at compile time.
Do they always operate at compile time? (like sizeof() in C++)
No. sizeof() is relatively unique.
Edit:
To show that operator in user defined class behave just like functions here is an example of using mem_fun_ref
#include <vector>
#include <algorithm>
#include <memory>
#include <functional>
class X
{
public:
// Non standard operators.
// Because std::mem_fun_ref has a known weakness in that it can
// not be used with methods that take parameters be reference.
//
// The principle is the same though. That the operator+ can be
// used anywhere that the add() method can be used.
X& operator+(X* rhs) { return *this;}
X& add(X* rhs) { return *this;}
};
typedef X& (X::*MEMF)(X* rhs);
int main()
{
MEMF p1 = &X::add;
MEMF p2 = &X::operator+;
X value;
std::vector<X> data;
std::for_each(data.begin(),
data.end(),
std::bind2nd(std::mem_fun_ref(&X::operator+),&value));
}
There is no meaningful difference between operators and functions, except that operators have a different syntax. Primitive operators however are not functions.
What is operator?
An operator is generally an operation performed on a variable given some form of punctuation. For example, the default behavior of operator+ between two integers is to add them.
What is function?
A function is a subroutine -- a reuseable block of code.
What is the difference between them?
Nothing, as far as user code is concerned, except for syntax. Note that if you override operator||, operator&&, or (to a lesser extent) operator,, you change the semantics of the built in operator semantics. In the case of && and ||, you make the operation which is normally short circuiting into an operation which is not. In the case of the comma, you would need to ensure that you evaluate the arguments left to right, as the comma operator normally behaves in this way.
Is user-defined operator+() a function or operator?
Neither. It is a user defined operator overload. A function name cannot start with the keyword operator, and an operator is simply the actual punctuation mark used to invoke the operator overload, i.e. + or -. EDIT: Note that while technically speaking it is not a function, it does have the semantics of a function call, as demonstrated in #Martin York's excellent answer.
Can operator operate on operands at compile-time? Do they always operate at compile time? (like sizeof() in C++)
No, sizeof cannot be overloaded. If you want some form of compile time operation done, you need to use something like template metaprogramming. Note that if the compiler is able to do the calculation at compile time it may elide the call into your overloaded operator, of course.
In C++ you can override what the symbols +, -, ==, etc. do when applied to class instances. By defining the "operator+" method in class A, you are telling the compiler what to do with code like:
A a, b, c;
c = a + b; // the + here actually calls a.operator+(b)
It's also a function or more precisely an instance method, in the sense that it's something that gets called.
EDIT: see also http://en.wikipedia.org/wiki/Operator_overloading
and http://en.wikibooks.org/wiki/C++_Programming/Operators/Operator_Overloading
There is no huge difference between functions and operators. You can think of an using operator, e.g., 'a+b', as a shortcut to the function operator+(a,b) which is defined for the types of a and b. Of course, operators on primitive types (like integers) and a few other exceptions are not necessarily defined like this.
Thus, to answer a few of your specific questions:
Is user-defined operator+() a function or operator?
A function that implements an operator.
Can operator operate on operands at compile-time? Do they always operate at compile time?
Since it is a function, it operates at run time, but in some cases compiler optimizations can do work at compile time for certain operators. I'm not 100% sure why you're asking this, so perhaps there is something I'm not aware of here.
There are only two minor differences between functions and operators.
Operators can be used in two ways (x+y or operator+(a,b)).
Operators must have same number of parameters as the built-in one (operator== must have exactly two params). The exception from this rule is function call operator() which can be overloaded with any number of any parameters.
Here are some differences between an operator and a function:
An operator does not push its parameters onto the stack, but a function pushes its parameters onto the stack.
The compiler knows about the operation of the operators, but is not aware of the output of the function. Said a different way, the action of the operator is defined at compilation time and that of a function is defined at the runtime.

C++ logical operators return value

Here is some code I'm writing in C++. There's a call to an addAVP() function
dMessage.addAVP(AVP_DESTINATION_HOST, peer->getDestinationHost() || peer->getHost());
which has two versions: one overloaded in the second parameter to addAVP(int, char*) and another to addAVP(int, int). I find the C++ compiler I use calls the addAVP(int, int) version which is not what I wanted since getDestinationHost() and getHost() both return char*.
Nonetheless the || operator is defined to return bool so I can see where my error is. Bool somehow counts as an integer and this compiles cleanly and calls the second addAVP().
Lately I'm using a lot of dynamically typed languages, i.e. lisp, where the above code is correct can be written without worries. Clearly, clearly the above code in C++ is a big error, but still have some questions:
Should I be using this kind of shortcut, i.e. using the ||-operator's return value, at all in C++. Is this compiler dependent?
Imagine that I really, really had to write the nice a || b syntax, could this be done cleanly in C++? By writing an operator redefinition? Without losing performance?
As a followup to my original request, or my own answer to 2 :-) I was thinking along the lines of using a class to encapsulate the (evil?) rawpointer:
class char_ptr_w {
const char* wrapped_;
public:
char_ptr_w(const char* wrapped) : wrapped_(wrapped) {}
char_ptr_w(char_ptr_w const& orig) { wrapped_=orig.wrapped(); }
~char_ptr_w() {}
inline const char* wrapped() const { return wrapped_; }
};
inline char_ptr_w operator||(char_ptr_w &lhs, char_ptr_w& rhs) {
if (lhs.wrapped() != NULL)
return char_ptr_w(lhs.wrapped());
else
return char_ptr_w(rhs.wrapped());
};
Then I could use:
char_ptr_w a(getDestinationHost());
char_ptr_w b(getHost());
addAVP(AVP_DESTINATION_HOST, a || b);
In which this addAVP would be overloaded for char_ptr_w. According to my tests, this generates at most the same assembly code as ternary a?b:c solution, particularly because of the NRVO optimization in the operator, which does not, in most compilers, call the copy-constructor (although you have to include it).
Naturally, in this particular example I agree that the ternary solution is the best. I also agree that operator redefinition is something to be taken with care, and not always beneficial. But is there anything conceptually wrong, in a C++ sense, with the above solution?
It is legal in C++ to overload the logic operators, but only if one or both of the arguments are of a class type, and anyway it's a very bad idea. Overloaded logic operators do not short circuit, so this may cause apparently valid code elsewhere in your program to crash.
return p && p->q; // this can't possibly dereference a null pointer... can it?
As you discovered, a bool is really an int. The compiler is picking the correct function for your footprint. If you want to keep similar syntax, you might try
char*gdh=0;
dMessage.addAVP(AVP\_DESTINATION\_HOST,
(gdh=peer->getDestinationHost()) ? gdh : peer->getHost());
I would strongly recommend against redefining the operator. From a maintenance perspective, this is very likely to confuse later developers.
Why are you using an "or" operator on two char pointers?
I am assuming that peer->getDestinationHost() or peer->getHost() can return a NULL, and you are trying to use the one that returns a valid string, right?
In that case you need to do this separately:
char *host = peer->getDestinationHost();
if(host == NULL)
host = peer->getHost();
dMessage.addAVP(AVP\_DESTINATION\_HOST, host);
It makes no sense to pass a boolean to a function that expects a char *.
In C++ || returns a bool, not one of its operands. It is usually a bad idea to fight the language.
1) Should I be using this kind of shortcut, i.e. using the ||-operator's return value, at all in C++. Is this compiler dependent?
It's not compiler dependent, but it doesn't do the same as what the || operator does in languages such as JavaScript or or in common lisp. It coerces it first operand to a boolean values, and if that operand is true returns true. If the first operand is false, the second is evaluated and coerced to a boolean value, and this boolean value is returned.
So what it is doing is the same as ( peer->getDestinationHost() != 0 ) || ( peer->getHost() != 0 ). This behaviour is not compiler dependent.
2) Imagine that I really, really had to write the nice a || b syntax, could this be done cleanly in C++? By writing an operator redefinition? Without losing performance?
Since you are using pointers to chars, you can't overload the operator ( overloading requires one formal parameter of a class type, and you've got two pointers ). The equivalent statement C++ would be to store the first value in a temporary variable and then use the ?: ternary operator, or you can write it inline with the cost of evaluating the first expression twice.
You could instead do something like:
dMessage.addAVP(AVP_DESTINATION_HOST, (peer->getDestinationHost())? peer->getDestinationHost() : peer->getHost());
This is not as neat as || but near to it.
Well, you're right about what the problem is with your code: a || b will return a bool, which is converted to int (0 for false, != 0 for true).
As for your questions:
I'm not sure whether the return value is actually defined in the standard or not, but I wouldn't use the return value of || in any context other than a bool (since it's just not going to be clear).
I would use the ? operator instead. The syntax is: (Expression) ? (execute if true) : (execute if false). So in your case, I'd write: (peer->getDestinationHost() =! NULL) ? peer->getDestinationHost() : peer->getHost(). Of course, this will call getDestinationHost() twice, which might not be desirable. If it's not, you're going to have to save the return value of getDestinationHost(), in which case I'd just forget about making it short and neat, and just use a plain old "if" outside of the function call. That's the best way to keep it working, efficient, and most importantly, readable.