Decide which member function to call by ternary operator - c++

If I want to call function foo on an object thisThing (in C# jargon, this is called the "receiver", so I'll call it that here too) and pass the argument myStuff, I'll do it like this:
thisThing.foo(myStuff);
Super simple, nothing surprising going on here.
If I want to change the argument to yourStuff if a bool value b is false, I'll do it like this:
thisThing.foo(b ? myStuff : yourStuff);
Also very simple, basic use of the ternary operator.
If I want to change the receiver to otherThing if b is false, I'll do it like this:
(b ? thisThing : otherThing).foo(myStuff);
A little bit weirder, you probably don't do this super often, but it's nothing crazy either.
But if I want to change the called function to bar if b is false, how do I do that?
I would think something like this:
thisThing.(b ? foo : bar)(myStuff);
But of course, this does not work.
Is there a simple, neat-looking, performant way of doing this, preferrably without redundantly specifying anything?
There will probably have to be some compromises made, but the point is to not have to repeat the receiver and arguments. So the following works:
if (b)
{
thisThing.foo(myStuff);
}
else
{
thisThing.bar(myStuff);
}
But you have to repeat the receiver and arguments. Imagine that thisThing and myStuff are placeholders for much more complex expressions. You might want to put those in local variables first, but that has implications for copying, and it does not play nicely if you have many arguments.
You might be able to take function pointers to those member functions and then do something like (b ? pointerToFoo : pointerToBar)(myStuff);, but dealing with function pointers tends to be messy (think function overloading) and it does not seem like something that the compiler would properly optimize away. But I'd be happy to be proven wrong here.

You can use member function pointers, but you need special syntax to call the function via the pointer:
struct X {
void foo() {}
void bar() {}
};
int main() {
X thisThing;
bool b = false;
(thisThing.*(b ? &X::foo : &X::bar))();
}
However, I would not recommend to actually use it like this (unless there are reasons not shown in the question). Note that it won't work like this when foo or bar are overloaded.
Anyhow, in my opinion also your other examples are not good use-cases for the conditional operator. The conditional operator is not just a equivalent replacement for if-else. It has slightly different use-cases. Sometimes one uses the conditional operator to determine the common type of two expressions. Sometimes you cannot use an if-else. For example when initializing a reference:
int& x = a ? c : d; // cannot be done with if/else
My advice is: Don't use the conditional operator to save on typing compared to an if-else. The difference between if-else and the conditional operator is almost never the amount of code you have to write only.

What about:
thisThing.foo_or_bar(b, myStuff);
and:
ThingClass::foo_or_bar(bool b, SomeType myStuff)
{
if (b)
foo(myStuff);
else
bar(myStuff);
}

Similar to #463035818_is_not_a_number's answer, but rather than using the pointer to member operator(.*) and all the parentheses, I would use std::invoke instead:
struct X {
void foo() {}
void bar() {}
};
int main() {
X thisThing;
bool b = false;
std::invoke(b ? &X::foo : &X::bar, thisThing);
}
However, just like the original answer, this cannot be used if function overloads were included.

Related

How to immediately invoke a C++ lambda?

A constructor from a class I'm inheriting requires a non-trivial object to be passed in. Similar to this:
MyFoo::MyFoo() : SomeBase( complexstuff )
{
return;
}
The complexstuff has little to do with MyFoo, so I didn't want to have to pass it in.
Instead of writing some kind of 1-off temporary function that returns complexstuff I used a lambda. What took me a few minutes to figure out is I have to invoke the lambda. So my code now looks like this:
MyFoo::MyFoo() : SomeBase(
[]()
{
/* blah blah do stuff with complexstuff */
return complexstuff;
} () )
{
return;
}
If you didn't catch it, it is subtle. But after the lambda body, I had to put () to tell the compiler to immediately "run" the lambda. Which made sense after I figured out what I had done wrong. Otherwise, without the () to invoke the lambda, gcc says something similar to this:
error: no matching function for call to 'SomeBase(<lambda()>)'
But now that has me thinking -- did I do this correctly? Is there a better way in C++11 or C++14 to tell the compiler that I want it to immediately invoke a lambda I've written? Or is appending an empty () like I did the usual way to do this?
But now that has me thinking -- did I do this correctly?
Yes you did.
Is there a better way in C++11 or C++14 to tell the compiler that I want it to immediately invoke a lambda I've written?
Not that I know of. A lambda is also just a function object, so you need to have a () to call it, there is no way around it (except of course some function that invokes the lambda like std::invoke).
If you want you can drop the () after the capture list, because your lambda doesn't take any parameters.
Or is appending an empty () like I did the usual way to do this?
Yes, it is the shortest way. As said before, std::invoke would also work instead, but it requires more typing. I would say a direct call with () is the usual way it is done.
In C++17 you can use std::invoke. This does the exact same thing as you did, but perhaps you will find this clearer.
#include <iostream>
#include <functional>
void foo(int i)
{
std::cout << i << '\n';
}
int main()
{
foo( std::invoke( []() { return 1; } ) );
}
There's no way to tell the compiler to invoke the lambda immediately. The simplest course (both in terms of complexity and number of typed characters) is what you did already. It's also very idiomatic for anyone who has worked with languages that have closures (I'm thinking JavaScript here).
If you want to avoid the syntax, then either modify SomeBase or complexstuff to execute the callable.
If all you want is syntactic sugar for invoking the lambda, you can always do what something like Alexandrescu's SCOPE_GUARD does, and abuse operator overloading:
Live example
#include <iostream>
namespace detail {
enum class invoke_t{};
template<class Callable>
auto operator+(invoke_t, Callable c) -> decltype(c()) {
return c();
}
}
constexpr detail::invoke_t invoke{};
int main() {
invoke + []() {
std::cout << "called";
};
}
But I wouldn't. Inventing your own DSL will just make your code worse to maintain. Stick to the idioms that utilize plain language constructs.
Is there a better way
You could also consider having a private static member function building the complexstuff, something like
class MyFoo : public Base {
private:
static SomeComplexType compute_complex_stuff() {
SomeComplexType complexstuff;
/*compute the complexstuff */
return complexstuff;
};
public:
MyFoo() : Base(compute_complex_stuff()) {};
};
I don't know if it is better than defining a lambda expression and applying it immediately; that is IMHO a matter of taste; for a short lambda body I would prefer a lambda expression immediately applied (but perhaps some compiler would create the temporary closure in that case, so it might be slower without optimizations; I expect most C++11 compilers to be able to make that optimization).
BTW, GCC provides the statement expression language extension (also understood by Clang) for your purposes. With it you could write
MyFoo::MyFoo : Base (({
SomeComplexType complexstuff;
/*compute the complexstuff */
return complexstuff;
}) {};

When an object provides both `operator!` and `operator bool`, which is used in the expression `!obj`?

I've ran across a question I am not able to answer for myself. Also, I didn't find an answer to this on both google and here. Say, I want to "check an object for validity" in an if clause, like so:
MyClass myObject;
// [some code, if any]
if (!myObject)
{
// [do something]
}
Let MyClass be defined something like this:
class MyClass
{
public:
MyClass() { };
virtual ~MyClass() { };
bool operator!()
{
return !myBool;
};
operator bool()
{
return myBool;
};
private:
bool myBool = 0;
};
My question now is: Which one of the overloaded operators is actually used in this if clause? Either way, the result is obviously the same.
It will use operator!.
A function whose parameter types match the arguments will be chosen in preference to one that requires type conversions.
You'll find that operator ! gets executed because it's the most direct resolution. If it used operator bool instead then it would have to call the conversion operator first, and then apply the ! separately to that.
As a general rule, it's a good idea to avoid that situation though. It's generally better just to define the bool conversion, because strictly speaking that's what you want your logical operators to act on, rather than MyClass directly. Defining both creates a bit of a readability problem, and is a form of redundant code duplication (which can lead to programmer error in future).

How and when to properly use *this pointer and argument matching?

When I go thru the code written by collegue, in certain place, they use:
this->doSomething(); //-->case A
doSomething(); //-->case B
In fact I'm not sure about the great usage of *this pointer...:(
Another question with argument matching:
obj.doOperation(); //-->case C
(&obj)->doOperation(); //-->case D
In fact both cases are performing the desired operation, is it simply a way to make the code look more complex?
What is your recommendation on the above two question? When is the appropriate time to use them and why?
This is not an answer to your question, but a note that both fragments may do different things:
namespace B { void doSomething() {} }
struct A {
void f()
{
using B::doSomething;
this->doSomething(); // call A::doSomething
doSomething(); // calls B::doSomething
}
int a;
void g(int a)
{
this->a = a; // assigns argument to member
}
A* operator & () { return this; }
void doOperation() {}
void doSomething() {}
};
void g(A &obj)
{
obj.doOperation(); // calls A::doOperation directly
(&obj)->doOperation(); // calls A::operator & first
}
Cases B and C are always the appropriate way. Cases A and D are equivalent and do nothing different.
A few exceptions to that:
If the class has an overloaded operator& that does surprising things, then case D could do something different that C. Actually having classes which do this is not recommended, since it would be confusing.
If there is a local variable doSomething (or something else of that name in the local scope), then A would refer to a different doSomething than B. Again it isn't recommended to get yourself into such a situation, better give different names to different things.
C and D are different. If doOperation is virtual, case D will perform the virtual call, case C will perform a non-virtual call if obj is not a reference. This assumes however that operator& and operator-> have not been overloaded.
I tend to use A over B since there may be a local doSomething identifier. Inside template code, things may get worse (although I can't come with a precise example right now). It is a good habit to take.

Private member function that takes a pointer to a private member in the same class

How can I do this? (The following code does NOT work, but I hope it explains the idea.)
class MyClass
{
....
private:
int ToBeCalled(int a, char* b);
typedef (MyClass::*FuncSig)(int a, char* b);
int Caller(FuncSig *func, char* some_string);
}
I want to call Caller in some way like:
Caller(ToBeCalled, "stuff")
and have Caller call ToBeCalled with whatever parameters it feels needs passing. If at all possible I want to keep everything encapsulated in the private part of my class. In reality, I'd have about 50 functions like ToBeCalled, so I can't see a way to avoid this.
Thanks for any suggestions. :)
You're most of the way there. You're missing the return type from the typedef, it should be
typedef int (MyClass::*FuncSig)(int, char*);
Now, you just need to use it properly:
int Caller(FuncSig func, int a, char* some_string)
{
return (this->*func)(a, some_string);
}
You want to pass around plain FuncSig instances, not FuncSig* -- a FuncSig* is a pointer to a pointer to a member function, with an extra unnecessary level of indirection. You then use the arrow-star operator (not its official name) to call it:
(object_to_be_called_on ->* func)(args);
For non-pointer objects (e.g. objects on the stack, or references to objects), you use the dot-star operator:
MyClass x;
(x .* func)(args);
Also, be wary of operator precedence -- the arrow-star and dot-star operators have lower precedence than function calls, so you need to put in the extra parentheses as I have done above.
I'm assuming you tried Caller(MyClass::ToBeCalled, "stuff") already, but is there any particular reason you need a function pointer? Also, please post the actual compiler error.

Optional function parameters: Use default arguments (NULL) or overload the function?

I have a function that processes a given vector, but may also create such a vector itself if it is not given.
I see two design choices for such a case, where a function parameter is optional:
Make it a pointer and make it NULL by default:
void foo(int i, std::vector<int>* optional = NULL) {
if(optional == NULL){
optional = new std::vector<int>();
// fill vector with data
}
// process vector
}
Or have two functions with an overloaded name, one of which leaves out the argument:
void foo(int i) {
std::vector<int> vec;
// fill vec with data
foo(i, vec);
}
void foo(int i, const std::vector<int>& optional) {
// process vector
}
Are there reasons to prefer one solution over the other?
I slightly prefer the second one because I can make the vector a const reference, since it is, when provided, only read, not written. Also, the interface looks cleaner (isn't NULL just a hack?). And the performance difference resulting from the indirect function call is probably optimized away.
Yet, I often see the first solution in code. Are there compelling reasons to prefer it, apart from programmer laziness?
I would not use either approach.
In this context, the purpose of foo() seems to be to process a vector. That is, foo()'s job is to process the vector.
But in the second version of foo(), it is implicitly given a second job: to create the vector. The semantics between foo() version 1 and foo() version 2 are not the same.
Instead of doing this, I would consider having just one foo() function to process a vector, and another function which creates the vector, if you need such a thing.
For example:
void foo(int i, const std::vector<int>& optional) {
// process vector
}
std::vector<int>* makeVector() {
return new std::vector<int>;
}
Obviously these functions are trivial, and if all makeVector() needs to do to get it's job done is literally just call new, then there may be no point in having the makeVector() function. But I'm sure that in your actual situation these functions do much more than what is being shown here, and my code above illustrates a fundamental approach to semantic design: give one function one job to do.
The design I have above for the foo() function also illustrates another fundamental approach that I personally use in my code when it comes to designing interfaces -- which includes function signatures, classes, etc. That is this: I believe that a good interface is 1) easy and intuitive to use correctly, and 2) difficult or impossible to use incorrectly . In the case of the foo() function we are implictly saying that, with my design, the vector is required to already exist and be 'ready'. By designing foo() to take a reference instead of a pointer, it is both intuitive that the caller must already have a vector, and they are going to have a hard time passing in something that isn't a ready-to-go vector.
I would definitely favour the 2nd approach of overloaded methods.
The first approach (optional parameters) blurs the definition of the method as it no longer has a single well-defined purpose. This in turn increases the complexity of the code, making it more difficult for someone not familiar with it to understand it.
With the second approach (overloaded methods), each method has a clear purpose. Each method is well-structured and cohesive. Some additional notes:
If there's code which needs to be duplicated into both methods, this can be extracted out into a separate method and each overloaded method could call this external method.
I would go a step further and name each method differently to indicate the differences between the methods. This will make the code more self-documenting.
While I do understand the complaints of many people regarding default parameters and overloads, there seems to be a lack of understanding to the benefits that these features provide.
Default Parameter Values:
First I want to point out that upon initial design of a project, there should be little to no use for defaults if well designed. However, where defaults' greatest assets comes into play is with existing projects and well established APIs. I work on projects that consist of millions of existing lines of code and do not have the luxury to re-code them all. So when you wish to add a new feature which requires an extra parameter; a default is needed for the new parameter. Otherwise you will break everyone that uses your project. Which would be fine with me personally, but I doubt your company or users of your product/API would appreciate having to re-code their projects on every update. Simply, Defaults are great for backwards compatibility! This is usually the reason you will see defaults in big APIs or existing projects.
Function Overrides:
The benefit of function overrides is that they allow for the sharing of a functionality concept, but with with different options/parameters. However, many times I see function overrides lazily used to provide starkly different functionality, with just slightly different parameters. In this case they should each have separately named functions, pertaining to their specific functionality (As with the OP's example).
These, features of c/c++ are good and work well when used properly. Which can be said of most any programming feature. It is when they are abused/misused that they cause problems.
Disclaimer:
I know that this question is a few years old, but since these answers came up in my search results today (2012), I felt this needed further addressing for future readers.
I agree, I would use two functions. Basically, you have two different use cases, so it makes sense to have two different implementations.
I find that the more C++ code I write, the fewer parameter defaults I have - I wouldn't really shed any tears if the feature was deprecated, though I would have to re-write a shed load of old code!
A references can't be NULL in C++, a really good solution would be to use Nullable template.
This would let you do things is ref.isNull()
Here you can use this:
template<class T>
class Nullable {
public:
Nullable() {
m_set = false;
}
explicit
Nullable(T value) {
m_value = value;
m_set = true;
}
Nullable(const Nullable &src) {
m_set = src.m_set;
if(m_set)
m_value = src.m_value;
}
Nullable & operator =(const Nullable &RHS) {
m_set = RHS.m_set;
if(m_set)
m_value = RHS.m_value;
return *this;
}
bool operator ==(const Nullable &RHS) const {
if(!m_set && !RHS.m_set)
return true;
if(m_set != RHS.m_set)
return false;
return m_value == RHS.m_value;
}
bool operator !=(const Nullable &RHS) const {
return !operator==(RHS);
}
bool GetSet() const {
return m_set;
}
const T &GetValue() const {
return m_value;
}
T GetValueDefault(const T &defaultValue) const {
if(m_set)
return m_value;
return defaultValue;
}
void SetValue(const T &value) {
m_value = value;
m_set = true;
}
void Clear()
{
m_set = false;
}
private:
T m_value;
bool m_set;
};
Now you can have
void foo(int i, Nullable<AnyClass> &optional = Nullable<AnyClass>()) {
//you can do
if(optional.isNull()) {
}
}
I usually avoid the first case. Note that those two functions are different in what they do. One of them fills a vector with some data. The other doesn't (just accept the data from the caller). I tend to name differently functions that actually do different things. In fact, even as you write them, they are two functions:
foo_default (or just foo)
foo_with_values
At least I find this distinction cleaner in the long therm, and for the occasional library/functions user.
I, too, prefer the second one. While there are not much difference between the two, you are basically using the functionality of the primary method in the foo(int i) overload and the primary overload would work perfectly without caring about existence of lack of the other one, so there is more separation of concerns in the overload version.
In C++ you should avoid allowing valid NULL parameters whenever possible. The reason is that it substantially reduces callsite documentation. I know this sounds extreme but I work with APIs that take upwards of 10-20 parameters, half of which can validly be NULL. The resulting code is almost unreadable
SomeFunction(NULL, pName, NULL, pDestination);
If you were to switch it to force const references the code is simply forced to be more readable.
SomeFunction(
Location::Hidden(),
pName,
SomeOtherValue::Empty(),
pDestination);
I'm squarely in the "overload" camp. Others have added specifics about your actual code example but I wanted to add what I feel are the benefits of using overloads versus defaults for the general case.
Any parameter can be "defaulted"
No gotcha if an overriding function uses a different value for its default.
It's not necessary to add "hacky" constructors to existing types in order to allow them to have default.
Output parameters can be defaulted without needing to use pointers or hacky global objects.
To put some code examples on each:
Any parameter can be defaulted:
class A {}; class B {}; class C {};
void foo (A const &, B const &, C const &);
inline void foo (A const & a, C const & c)
{
foo (a, B (), c); // 'B' defaulted
}
No danger of overriding functions having different values for the default:
class A {
public:
virtual void foo (int i = 0);
};
class B : public A {
public:
virtual void foo (int i = 100);
};
void bar (A & a)
{
a.foo (); // Always uses '0', no matter of dynamic type of 'a'
}
It's not necessary to add "hacky" constructors to existing types in order to allow them to be defaulted:
struct POD {
int i;
int j;
};
void foo (POD p); // Adding default (other than {0, 0})
// would require constructor to be added
inline void foo ()
{
POD p = { 1, 2 };
foo (p);
}
Output parameters can be defaulted without needing to use pointers or hacky global objects:
void foo (int i, int & j); // Default requires global "dummy"
// or 'j' should be pointer.
inline void foo (int i)
{
int j;
foo (i, j);
}
The only exception to the rule re overloading versus defaults is for constructors where it's currently not possible for a constructor to forward to another. (I believe C++ 0x will solve that though).
I would favour a third option:
Separate into two functions, but do not overload.
Overloads, by nature, are less usable. They require the user to become aware of two options and figure out what the difference between them is, and if they're so inclined, to also check the documentation or the code to ensure which is which.
I would have one function that takes the parameter,
and one that is called "createVectorAndFoo" or something like that (obviously naming becomes easier with real problems).
While this violates the "two responsibilities for function" rule (and gives it a long name), I believe this is preferable when your function really does do two things (create vector and foo it).
Generally I agree with others' suggestion to use a two-function approach. However, if the vector created when the 1-parameter form is used is always the same, you could simplify things by instead making it static and using a default const& parameter instead:
// Either at global scope, or (better) inside a class
static vector<int> default_vector = populate_default_vector();
void foo(int i, std::vector<int> const& optional = default_vector) {
...
}
The first way is poorer because you cannot tell if you accidentally passed in NULL or if it was done on purpose... if it was an accident then you have likely caused a bug.
With the second one you can test (assert, whatever) for NULL and handle it appropriately.