I need a way to force calling a constant version of member function. I'm trying to make it efficient as possible. Any good solutions?
EDIT: looking for a generic function
Make a reference to a const Type, or a pointer to a const Type.
You can do that in a fancy way, but at the end of the day, that's the only way.
Though really I don't see what the purpose of this is. Seems like it's not worth the effort.
Also, I'm not quite sure I understand what you mean by a generic function. That needs some clarification, but if I understand correctly, you want to take a pointer/value/reference and pass it to a function and have it magically call a const method? That would only work if polymorphism or at least a method of the same name (templating) could be used.
It automatically calls the const or non-const version depending on which parameter is passed. You can only cast from const to non-const. That may seem silly, but it is the way of the world.
For instance, you could normally do this:
void function(char foo);
void function(int foo);
function(4);
The compiler will "decide for you" which one to call, you can make it explicit by doing
int x;
function((int)x);
function((char)x);
However there is no equivalent for explicitly passing an overloaded const version.
Of course, you can simply only define a const version, and parameters will simply be passed as const.
Related
Ive searched through the archived posts but I couldnt find anything similar.
Just a simple question: whats the best practice in declaring inspecting functions like:
int foo(int a) const { return a+1; }
Im referring to the const keyword, do you usually declare it at the end of an inspecting function? Im just asking because I usually do, even if 99% I wont declare any const class.. I just keep on tellin myself that it could save me some time if I ever should need to, but I was wondering if anybody else really cares about declaring const functions or if Im just paranoid about typesafe code
Assuming that you are talking about member functions (non member functions cannot be const ever), you should write const-correct code always, and that means that each and every function that does not modify the visible state of the object should be const.
Even if you don't ever create a constant object of the type, in many cases you will pass the object to a function through const references and in that case, only const member functions can be called on the object (Incidentally this means that you should pass the object by constant reference to any function that does not need to change the state of the received object)
The const appended at the end of the function declaration and definition indicates a contract between the caller of the function and the function that the function will not modify any members of that class.
So if your function provides guarantee for such an const-correctness contract you should extend it to users of your function.
Yes, of course you should if you want your program to support const correctness.
Const correctness has a way of propagating through your program once you begin declaring instances as const. As program complexity and your use of const increases, then you will either:
encounter many compiler errors when using const objects if you do not add them now
or your program will build without (or fewer) errors once you favor using const in the appropriate places.
or you may end up avoiding const for some time - which is (IMO) not a good road to go down if you want to improve your designs.
Over time, many of us have learned to use const in more than 1% of our code.
I'm receiving the following warning:
warning: converting from 'void (MyClass::*)(byte)' to 'void (*)(byte)'
This is because I need to pass as argument a member function instead of an ordinary function. But the program is running correctly.
I'd like to disable this warning (Wno-bad-function-cast doesn't work for C++) or to implement a different way to pass a member function.
No. Take this warning seriously. You should rather change your code to handle this scenario.
Pointer to member function(void (MyClass::*)(byte)) and normal function pointer (void (*)(byte)) are entirely different. See this link. You cannot cast them just like that. It results in undefined behavior or crash.
See here, how they are different:
void foo (byte); // normal function
struct MyClass {
void foo (byte); // member function
}
Now you may feel that, foo(byte) and MyClass::foo(byte) have same signature, then why their function pointers are NOT same. It's because, MyClass::foo(byte) is internally resolved somewhat as,
void foo(MyClass* const this, byte);
Now you can smell the difference between them.
Declare pointer to member function as,
void (MyClass::*ptr)(byte) = &MyClass::foo;
You have to use this ptr with the object of MyClass, such as:
MyClass obj;
obj.*ptr('a');
You can't pass a function that takes two arguments to a place that expects a function that takes one. Can't be done, forget about it, period, end of story. The caller passes one argument to your function. It doesn't know about the second argument, it doesn't pass it to your function, you can't make it do what you want however hard you try.
For the very same reason you can't pass a non-static member function where a regular function is expected. A member function needs an object to operate on. Whatever code calls your function doesn't know about the object, there's no way to pass it the object, and there's no way to make it use the right calling sequence that takes the object into account.
Interfaces that take user's functions, without taking additional data that the user might want to pass to his function, are inherently evil. Look at the qsort() function from the C standard library. That's an example of an evil interface. Suppose you want to sort an array of string according to some collation scheme defined externally. But all it accepts is a comparison function that takes two values. How do you pass that collation scheme to your comparison function? You can't, and so if you want it working, you must use an evil global variable, with all the strings attached to it.
That's why C++ has moved away from passing function pointers around, and towards function objects. Function objects can encapsulate whatever data you want.
Also, this may be helpful
union FuncPtr
{
void (* func)(MyClass* ptr, byte);
void (MyClass::* mem_func)(byte);
};
If I have this code:
void Foo(aBasicType aIn) //Where aBasicType is int, char etc.
{
//...
}
Is there any point in making it const aBasicType since it is going to be copied anyway? One of the reasons I am asking is because I have seen it in 3rd party code and was wondering if there is something I am not aware of.
It cannot hurt to declare it const if you know that your function needs not modify its value during execution.
Note that functions that change their arguments, when arguments are passed by value, should be rare.
Declaring your variable const can prevent you from writing if (aIn = someValue).
I sometimes (infrequently) do it, when there is temptation to modify aIn in-place instead of making another copy, yet the method relies on aIn remaining unchanged throughout. It tends to be a close call though.
The reason is informative: you want the compiler to warn/error when a value-passed argument is seen on the left of an assignment.
It's a bit cumbersome, seen on libs whose audience may be less than "well informed" on C or C++ (it's the same for both languages).
That would make the value const for that function, which might be useful in the same way declaring a constant at the top of your function might be useful.
No, adding const to a scalar call-by-value parameter is meaningless and will only be confusing.
I prefer to add const qualifier to input paramters regardless to parameter passing method (by value, by pointer or by reference). So const parameter simply means "input parameter" and non-const parameter means "output parameter" (or, rarely, inout parameter). I suppose such a convention makes code more understandable but it is matter of taste, of course.
I think I can formulate this much simpler. When footype is not a template parameter:
const footype & in the signature is a guarantee for the caller of
the function and a constraint for the implementer of the function.
const footype on the other hand is only a constraint for the
implementer and irrelevant to the caller.
When footype is a template parameter, then the rules can only be tested against the individual template instantiations.
BTW, if you see const constraints, then the connected code is much easier to read because the possibilities of what the code can do is much restricted. This is one of the many reasons why C++ is easier to read than C# or Java.
Suppose I have this:
void func(WCHAR* pythonStatement) {
// Do something with pythonStatement
}
And I need to convert it to void function(void) like this:
bind(func, TEXT("console.write('test')"))
Now I have struct like this:
typedef void (__cdecl * PFUNCPLUGINCMD)();
struct FuncItem {
PFUNCPLUGINCMD pFunc;
// ...
};
How can I set the pFunc of my struct to bind(func, "something")? Bind returns lambda_functor not a function pointer, so how can I cast this functor to function pointer?
Thanks.
Ended up using the wrapping "solution" (GitHub)
I think that you can't, unless you make the resulting lamba_functor a global variable.
In that case, you could declare a function that invokes it:
void uglyWorkaround() {
globalLambdaFunctor();
}
and set pFunc to uglyWorkaround().
EDIT
Just a sidenote: if you are binding static text to the function call, you may completely omit bind() call and write just:
void wrapper() {
func(TEXT("console.write('test')"));
}
and set pFunc to wrapper().
Bind returns lambda_functor not a function pointer, so how can I cast this functor to function pointer?
I don't think you can. However, off the top of my head, I can think of several alternatives:
Use boost::function<void()> (or std::function() if your compiler supports TR1 or C++11) instead of void (*)().
It has the ability to bind to just about anything with a somewhat compatible signature.
Put the whole code into a template, make PFUNCPLUGINCMD a template parameter, and let function template argument deduction figure out the exact type.
That's a variation on the former, actually, where you would use the result of bind() directly instead of having boost::function abstract away the gory details.
Create a wrapper that calls the functor returned by boost::bind().
A function template might help to let the compiler figure out the exact types and generate a suitable function, although I haven't tried to do that. However, since you cannot use the result of bind() as a template argument, but need to have give the function access to it nevertheless, you will need a global variable for this. (The ability to avoid this is one of the main advantages of function objects, a very versatile of which is std::function.)
Extend your PFUNCPLUGINCMD callback type to support a user-provided parameter. For C callbacks, this usually is a void*. However, if you pass the address of the object returned by bind() to your callback, you would need to convert it into a pointer to the correct type - which, AFAIK, depends on the arguments provided to bind(). In order to avoid that, you'd need to pass something that abstracts away the exact type. Again, std::function comes to the rescue.
The first idea would be the best, but it requires you to be able to change PFUNCPLUGINCMD. The last one might be best when PFUNCPLUGINCMD needs to be compatible with C, as it uses the common C callback idiom.
You can't do this, unless you want to write your own Just-In-Time compiler. Alternatively, if you control the receiving code, then you could use a boost::function<>, which will accept a variety of function types, including pointers and function objects like those produced by boost::bind.
Do you find it helpful?
Every time You know that method won't change state of the object you should declare it to be constant.
It helps reading your code. And it helps when you try to change state of the object - compiler will stop you.
As often as possible. Functions that don't need to change data members should be declared as const. This makes code more understandable and may give hint to the compiler for optimization.
When you have a const object, the only methods that the compiler will let you call are those marked safe by the const keyword. In fact, only member methods make sense as const methods.
In C++, every method of an object receives an implicit this pointer to the object; A const method will simply receive a const this pointer.
Assuming you're talking about methods, as in:
struct Example {
void f() const;
};
Then if they should be callable on a const object, the method should be const.
Not often enough....
While all the answers are correct, if you are using a libary that is not const correct then it is difficult to use const all the places you should use it.
If you have an old API that takes a char * that for all logical purposes should be a const char *, then you either have to forget const in your code or do some ugly casting. In that case I forget const.
I use const at almost every opportunity, and like the fact it provides both documentation of intent and enforces compliance with that intent. Language features don't get much better than that, and yet const is curiously unloved. (The reality seems to be that the majority of self-proclaimed C++ coders can't explain the difference between int*, int*const, const int* and const int*const.)
While it could never have happened due to its 'C' origins, I often think C++ would be a better language if const had been the default and a liberal sprinkling of (say) 'var' or some similar keyword was necessary to allow post-construction modification of variables.
I used to declare functions as const but now I rarely if ever do it anymore.
The main problem was that if I wanted to change a function from const to non-const, it would mean that all other const functions calling that function would also need to be changed to non-const.
That happened more often than I thought due to optimization. For example I had a GetData() function which used to return a pointer to the data, but I later optimized to only set up the data if GetData() ends up being called (which changes the object's state, so it's no longer a const function).
Same thing for other functions that could do some calculation without changing the object's state, but at some point it made more sense caching the result since the function was called many times and was a bottleneck.
Also in practice, at least for my project, I saw very little benefit from declaring my functions as const.