How to get the address of an overloaded member function? - c++

I'm trying to get a pointer to a specific version of an overloaded member function. Here's the example:
class C
{
bool f(int) { ... }
bool f(double) { ... }
bool example()
{
// I want to get the "double" version.
typedef bool (C::*MemberFunctionType)(double);
MemberFunctionType pointer = &C::f; // <- Visual C++ complains
}
};
The error message is "error C2440: 'initializing' : cannot convert from 'overloaded-function' to 'MemberFunctionType'"
This works if f is not overloaded, but not in the example above. Any suggestion?
EDIT
Beware, the code above did not reflect my real-world problem, which was that I had forgotten a "const" - this is what the accepted answer points out. I'll leave the question as it is, though, because I think the problem could happen to others.

Well, i'll answer what i put as comment already so it can be accepted. Problem is with constness:
class C
{
bool f(int) { ... }
bool f(double) const { ... }
bool example()
{
// I want to get the "double" version.
typedef bool (C::*MemberFunctionType)(double) const; // const required!
MemberFunctionType pointer = &C::f;
}
};
Clarification:
The original question didn't contain that const. I did a wild guess in the comments whether he possibly has f being a const member function in the real code (because at a yet earlier iteration, it turned out yet another thing was missing/different to the real-world code :p). He actually had it being a const member function, and told me i should post this as an answer.

Related

How do I explicitly call an exception-throwing method in C++?

I have a simple class:
class A {
public:
bool f(int* status = nullptr) noexcept {
if (status) *status = 1;
return true;
}
void f() {
throw std::make_pair<int, bool>(1, true);
}
};
int main() {
A a;
a.f(); // <- Ambiguity is here! I want to call 'void f()'
}
I want to resolve ambiguity of a method call in favour of the exception-throwing method by any means.
The rationale behind such interface:
To have the noexcept(true) and noexcept(false) interface,
To allow optionally get extra information via a pointer in the noexcept(false) variant - while the noexcept(true) variant will always pack this information inside an exception.
Is it possible at all? Suggestions for a better interface are also welcome.
Having functions with this kind of signatures is obviously a bad design as you've found out. The real solutions are to have different names for them or to lose the default argument and were presented already in other answers.
However if you are stuck with an interface you can't change or just for the fun of it here is how you can explicitly call void f():
The trick is to use function pointer casting to resolve the ambiguity:
a.f(); // <- ambiguity is here! I want to call 'void f()'
(a.*(static_cast<void (A::*)()>(&A::f)))(); // yep... that's the syntax... yeah...
Ok, so it works, but don't ever write code like this!
There are ways to make it more readable.
Use a pointer:
// create a method pointer:
auto f_void = static_cast<void (A::*)()>(&A::f);
// the call is much much better, but still not as simple as `a.f()`
(a.*f_void)();
Create a lambda or a free function
auto f_void = [] (A& a)
{
auto f_void = static_cast<void (A::*)()>(&A::f);
(a.*f_void)();
};
// or
void f_void(A& a)
{
auto f_void = static_cast<void (A::*)()>(&A::f);
(a.*f_void)();
};
f_void(a);
I don't know if this is necessary better. The call syntax is definitely simpler, but it might be confusing as we are switching from a method call syntax to a free function call syntax.
Both versions f have different meanings.
They should have two different name, as:
f for the throwing one, because using it means that your are confident on success, and failure would be an exception in the program.
try_f() or tryF() for the error-return based one, because using it means that failure of the call is an expected outcome.
Two different meanings should be reflected in the design with two different name.
Because it seems fundamentally obvious to me, I may be missing something or may not fully understand your question. However, I think this does exactly what you want:
#include <utility>
class A {
public:
bool f(int* status) noexcept {
if (status) *status = 1;
return true;
}
void f() {
throw std::make_pair<int, bool>(1, true);
}
};
int main() {
A a;
a.f(); // <- now calls 'void f()'
a.f(nullptr); // calls 'bool f(int *)'
}
I simply removed the default argument from the noexcept variant. It's still possible to call the noexcept variant by passing nullptr as an argument, which seems a perfectly fine way of indicating that you want to call that particular variant of the function - after all, there's going to have to be some syntactic marker indicating which variant you want to call!
I agree with other users' suggestions to simply remove the default argument.
A strong argument in favour of such a design is that it would be in line with the new C++17 filesystem library, whose functions typically offer callers the choice between exceptions and error reference parameters.
See for example std::filesystem::file_size, which has two overloads, one of them being noexcept:
std::uintmax_t file_size( const std::filesystem::path& p );
std::uintmax_t file_size( const std::filesystem::path& p,
std::error_code& ec ) noexcept;
The idea behind this design (which is originally from Boost.Filesystem) is almost identical to yours, except of the default argument. Remove it and you do it like a brand new component of the standard library, which obviously can be expected not to have a completely broken design.
In C++14 it's ambiguous because noexcept is not part of the function signature. With that said...
You have a very strange interface. Although f(int* status = nullptr) is labelled noexcept, because it has a twin that does throw a exception, you are not really giving the caller a logical exception guarantee. It seems you simultaneously want f to always succeed while throwing an exception if the precondition is not met (status has a valid value, i.e not nullptr). But if f throws, what state is the object in? You see, your code is very hard to reason about.
I recommend you take a look at std::optional instead. It'll signal to the reader what you are actually trying to do.
C++ already has a type specifically used as an argument to disambiguate between throwing and non-throwing variants of a function: std::nothrow_t. You can use that.
#include <new>
class A {
public:
bool f(std::nothrow_t, int* status = nullptr) noexcept {
if (status) *status = 1;
return true;
}
void f() {
throw std::make_pair<int, bool>(1, true);
}
};
int main() {
A a;
a.f(); // Calls 'void f()'
a.f(std::nothrow); // Calls 'void f(std::nothrow_t, int*)'
}
Though I would still prefer an interface where the name distinguishes the variants, or possibly one where the distinction isn't necessary.
Here's a purely compile-time method.
It may be useful if your compiler happens to have trouble optimizing away function pointer calls.
#include <utility>
class A {
public:
bool f(int* status = nullptr) noexcept {
if (status) *status = 1;
return true;
}
void f() {
throw std::make_pair<int, bool>(1, true);
}
};
template<void (A::*F)()>
struct NullaryFunction {
static void invoke(A &obj) {
return (obj.*F)();
}
};
int main() {
A a;
// a.f(); // <- Ambiguity is here! I want to call 'void f()'
NullaryFunction<&A::f>::invoke(a);
}
So you are trying to throw an exception if the code is unprepared for an error return?
Then, how about
class ret
{
bool success;
mutable bool checked;
int code;
public:
ret(bool success, int code) : success(success), checked(false), code(code) { }
~ret() { if(!checked) if(!success) throw code; }
operator void *() const { checked = true; return reinterpret_cast<void *>(success); }
bool operator!() const { checked = true; return !success; }
int code() const { return code; }
};
This is still an Abomination unto Nuggan though.
By removing the if(!success) check in the destructor, you can make the code throw whenever a return code is not looked at.

access the own interface with the scope operator doesnt work?

While playing around with polymorphism and templates i eventually dug up a strange (at least for me) behaviour of the scope operator. When i tried to access a method of a *b*aseclass using the *i*nterface with the scope operator within a *d*erived class, i get a linker error. I can only assume that the scope operator doesnt look into the vtable and tries to run the method directly from the interface, which is actually pure virtual.
Here is the example for that:
struct i
{
virtual void set(char* in, short len) = 0;
virtual char* getStr() = 0;
virtual ~i() {}
};
template <int size = 10>
struct b : public i // this one is like an char-Array
{
char str[size];
void set(char* in, short len) { memcpy(this->getStr(),in,len); }
char* getStr() { return str;}
};
template <int size = 10>
struct d : public b<size> // this one is like an cString
{
void set(char* in) { strcpy(this->getStr(),in); }
};
struct final : public d<4>
{
void test()
{
set("abc"); ///< Works
d<4>::set("abc"); ///< Works
//set("abc",3); ///< Error : no matching function for call to 'final::set(const char [4], int)' (its shadowed by d)
//note: candidates are: void d<size>::set(char*) [with int size = 4]
b<4>::set("abc",3); ///< Works
//i::set("abc",3); ///< Linker Error: (.gnu.linkonce.t._ZN5final4testEv+0x68) : Error : undefined reference to `i::set(char*, short)'
//this->set("abc",3); ///< Error : no matching function for call to 'final::set(const char [4], int)' (its shadowed by d too)
((i*) this)->set("abc",3); ///< Works!
}
};
int main()
{
final f;
f.test();
return 0;
}
The background why i tried this, is to avoid changing the template parameter of every call to a templated base class, when i might change the size of the final class.
So can somebody explain me why this happens with the scope operator?
Funny is that it does work, when casting the "this" pointer to a interface pointer and then using the baseclass's method with that. Is this actually valid and practicable?
BTW: i use GCC 4.1.2
EDIT:
Just to clarify, i know d::set is shadowing b::set .. thats not the problem, i am just asking about the linker error!
When you write Base::symbol in a class context, symbol will
always be resolved statically, with name lookup starting in the
class Base. The reason is simple: that's the way you access
masked members in derived classes. Otherwise, you'd be unable
to chain functions, e.g.:
void
Derived::function()
{
Base::function(); // calls the function in Base before doing anything else.
// ...
}
At the time C++ was being developed, this was felt to be
important, and even today, you'd want to support some way of
doing it.
One idea for working around this:
template <int size=10>
struct d : public b<size>
{
typedef b<size> Base;
// ...
};
Then in final, refer to Base::set.
Oh i finally found the answer to my question by myself:
Polymorphism needs a indirection!
As stated here: Polymorphic objects on the stack?
Thanks for pointing THAT out ;)

Get function address from a function structure member

I'm trying to get function addresses which are hidden behind structures. Unfortunately, the void* basic C++ conversion doesn't work, so I used C++ template instead.
1. Basic void* C++ conversion doesn't work with functions inside structures, why?
void * lpfunction;
lpfunction = scanf; //OK
lpfunction = MessageBoxA; //OK
I made a simple structure :
struct FOO{
void PRINT(void){printf("bla bla bla");}
void SETA(int){} //nothing you can see
void SETB(int){} //nothing you can see
int GETA(void){} //nothing you can see
int GETB(void){} //nothing you can see
};
///////////////////////////////////////////
void *lpFunction = FOO::PRINT;
And the compiling error :
error C2440: 'initializing' :
cannot convert from 'void (__thiscall FOO::*)(void)' to 'void *'
2. Is getting function member addresses impossible?
Then, I made a template function which is able to convert a function member to address. Then I will call it by assembly. It should be something like this:
template <class F,void (F::*Function)()>
void * GetFunctionAddress() {
union ADDRESS
{
void (F::*func)();
void * lpdata;
}address_data;
address_data.func = Function;
return address_data.lpdata; //Address found!!!
}
And here is the code :
int main()
{
void * address = GetFunctionAddress<FOO,&FOO::PRINT>();
FOO number;
number.PRINT(); //Template call
void * lpdata = &number;
__asm mov ecx, lpdata //Attach "number" structure address
__asm call address //Call FOO::PRINT with assembly using __thiscall
printf("Done.\n");
system("pause");
return 0;
}
But, I see it is extremely specific. It looks like LOCK - KEY, and I have to make a new template for every set of argument types.
Original (OK) :
void PRINT(); //void FOO::PRINT();
Modify a bit :
void PRINT(int); //void FOO::PRINT(int);
Immediately with old template code the compiler shows :
//void (F::*func)();
//address_data.func = Function;
error C2440: '=' : cannot convert from
'void (__thiscall FOO::*)(int)' to 'void (__thiscall FOO::*)(void)'
Why? They are only addresses.
69: address_data.func = Function;
00420328 mov dword ptr [ebp-4],offset #ILT+2940(FOO::PRINT) (00401b81)
...
EDIT3 : I know the better solution :
void(NUMBER::*address_PRINT)(void) = FOO::PRINT;
int(NUMBER::*address_GETA)(void) = FOO::GETA;
int(NUMBER::*address_GETB)(void) = FOO::GETB;
void(NUMBER::*address_SETA)(int) = FOO::SETA;
void(NUMBER::*address_SETA)(int) = FOO::SETB;
It's much better than template. And by the way I want to achieve the goal :
<special_definition> lpfunction;
lpfunction = FOO::PRINT; //OK
lpfunction = FOO::GETA; //OK
lpfunction = FOO::GETB; //OK
lpfunction = FOO::SETA; //OK
lpfunction = FOO::SETB; //OK
Is this possible?
Pointers to member functions are nothing like pointers to global functions or static member functions. There are many reasons for this, but I'm not sure how much you know about how C++ works, and so I'm not sure what reasons will make sense.
I do know that what you are trying in assembly simply won't work in the general case. It seems like you have a fundamental misunderstanding about the purpose of member functions and function pointers.
The thing is, you are doing some things that you would generally not do in C++. You don't generally build up tables of function pointers in C++ because the things you would use that sort of thing for are what virtual functions are for.
If you are determined to use this approach, I would suggest you not use C++ at all, and only use C.
To prove these pointer types are completely incompatible, here is a program for you:
#include <cstdio>
struct Foo {
int a;
int b;
int addThem() { return a + b; }
};
struct Bar {
int c;
int d;
int addThemAll() { return c + d; }
};
struct Qux : public Foo, public Bar {
int e;
int addAllTheThings() { return Foo::addThem() + Bar::addThemAll() + e; }
};
int addThemGlobal(Foo *foo)
{
return foo->a + foo->b;
}
int main()
{
int (Qux::*func)();
func = &Bar::addThemAll;
printf("sizeof(Foo::addThem) == %u\n", sizeof(&Foo::addThem));
printf("sizeof(Bar::addThemAll) == %u\n", sizeof(&Bar::addThemAll));
printf("sizeof(Qux::addAllTheThings) == %u\n", sizeof(&Qux::addAllTheThings));
printf("sizeof(func) == %u\n", sizeof(func));
printf("sizeof(addThemGlobal) == %u\n", sizeof(&addThemGlobal));
printf("sizeof(void *) == %u\n", sizeof(void *));
return 0;
}
On my system this program yields these results:
$ /tmp/a.out
sizeof(Foo::addThem) == 16
sizeof(Bar::addThemAll) == 16
sizeof(Qux::addAllTheThings) == 16
sizeof(func) == 16
sizeof(addThemGlobal) == 8
sizeof(void *) == 8
Notice how the member function pointer is 16 bytes long. It won't fit into a void *. It isn't a pointer in the normal sense. Your code and union work purely by accident.
The reason for this is that a member function pointer often needs extra data stored in it related to fixing up the object pointer it's passed in order to be correct for the function that's called. In my example, when called Bar::addThemAll on a Qux object (which is perfectly valid because of inheritance) the pointer to the Qux object needs to be adjusted to point at the Bar sub-object before the function is called. So Qux::*s to member functions must have this adjustment encoded in them. After all, saying func = &Qux::addAllTheThings is perfectly valid, and if that function were called no pointer adjustment would be necessary. So the pointer adjustment is a part of the function pointer's value.
And that's just an example. Compilers are permitted to implement member function pointers in any way they see fit (within certain constraints). Many compilers (like the GNU C++ compiler on a 64-bit platform like I was using) will implement them in a way that do not permit any member function pointer to be treated as at all equivalent to normal function pointers.
There are ways to deal with this. The swiss-army knife of dealing with member function pointers is the ::std::function template in C++11 or C++ TR1.
An example:
#include <functional>
// .... inside main
::std::function<int(Qux *)> funcob = func;
funcob can point at absolutely anything that can be called like a function and needs a Qux *. Member functions, global functions, static member functions, functors... funcob can point at it.
That example only works on a C++11 compiler though. But if your compiler is reasonably recent, but still not a C++11 compiler, this may work instead:
#include <tr1/functional>
// .... inside main
::std::tr1::function<int(Qux *)> funcob = func;
If worse comes to worse, you can use the Boost libraries, which is where this whole concept came from.
But I would rethink your design. I suspect that you will get a lot more milage out of having a well thought out inheritance hierarchy and using virtual functions than you will out of whatever it is you're doing now. With an interpreter I would have a top level abstract 'expression' class that is an abstract class for anything that can be evaluated. I would give it a virtual evaluate method. Then you can derive classes for different syntax elements like an addition expression a variable or a constant. Each of them will overload the evaluate method for their specific case. Then you can build up expression trees.
Not knowing details though, that's just a vague suggestion about your design.
Here is a clean solution. By means of a template wrap your member function into a static member function. Then you can convert it to whatever pointer you want:
template<class F, void (F::*funct)()>
struct Helper: public T {
static void static_f(F *obj) {
((*obj).*funct)();
};
};
struct T {
void f() {
}
};
int main() {
void (*ptr)(T*);
ptr = &(Helper<T,&T::f>::static_f);
}
It seems that you need to convert a pointer to a member function to a void *. I presume you want to give that pointer as a "user data" to some library function and then you will get back your pointer and want to use it on some given object.
If this is the case a reinterpret_cast<void *>(...) could be the right thing... I assume that the library receiving the pointer is not using it.

Passing map<>::iterator as map<>::const_iterator &

I have a problem passing a map<...>::iterator object to a function as a const_iterator & on GCC:
class MyClass {
};
bool MyClass::_GetInstList(map<string,InstList>::const_iterator & it, const string & sMod)
{
cout<<"Matched\n";
it = tInstancesData.find(sMod);
if( it == tInstancesData.end() ) {
cout<<"\""<<sMod<<"\" is NOT a module\n";
return false;
}
return true;
}
bool SomeFunction()
{
map<string,InstList>::iterator it;
if( ! _GetInstList(it, SomeString) ) return false;
it->second.Add(...); // Modifying element pointed by "it"
}
My probelm is that on Visual Studio 2010 the code above works perfectly fine, but on GCC 4.1.2 I get an error saying there is no matching function to the function call, for _GetInstList(it, SomeString). The issue seems to be converting iterator to const_iterator &.
I have to take it by reference because "it" gets changed inside _GetInstList() and the caller function checks it. (The "it" pointer is changed not a pointed element).
Also, the "it" in SomeFunction() cannot be const because it changes an element.
How can I resolve this?
EDIT:
For those who suggest that the problem is the conversion from iterator to const_iterator:
The code compiles fine if the function prototype is changed to take const_iterator NOT as a reference, the problem is the const &.
Change your argument type to const map<string,InstList>::const_iterator& or just a map<string,InstList>::const_iterator.
Here's an example demonstrating your problem (and the solution) with simple types:
void func1(double& x){}
void func2(const double& x){}
int main()
{
int x;
func1(x); // error: 'func1' : cannot convert parameter 1 from 'int' to 'double &'
func2(x); // succeeds
}
I think maybe this method should be redesigned anyway. Passing iterators around is messy and confusing for others to read. How hard would it be to do that?

Container of pointers

I'm having some trouble in declaring a STL Set of pointers to class instances. More specifically, I have this scenario:
class SimulatedDiskFile {
private:
// ...
public:
// ...
struct comparator {
bool operator () (SimulatedDiskFile* const& file_1, SimulatedDiskFile* const& file_2) {
return ((*file_1)->getFileName() < (*file_2)->getFileName());
}
};
}
typedef set<SimulatedDiskFile*, SimulatedDiskFile::comparator> FileSet;
The code above is not working. Compiler says it didn't find a member SimulatedDiskFile::comparator() function. If I put the function with this declaration (outside the struct), compiler says it was expecting a type.
Now here com my doubts (not only one, but related, I guess):
What is the the correct declaration for a set of pointers?
What is the correct declaration for a comparison funcion that compares pointers?
I did look up in many places before posting, but I found the references confusing and not quite related to my special case (as stupidly trivial as I think it is - actually, maybe this is the cause). So, any good links are of great help too!
Thanks in advance!
Fixing a few glitches,
#include <set>
class SimulatedDiskFile {
public:
int getFileName() { return 23; }
struct comparator {
bool operator () (SimulatedDiskFile* file_1, SimulatedDiskFile* file_2) {
return (file_1->getFileName() < file_2->getFileName());
}
};
};
typedef std::set<SimulatedDiskFile*, SimulatedDiskFile::comparator> FileSet;
compiles just fine.
Since you aren't showing where the 'getFileName()' method is supposed to be, I'm just going to go out on a limb and assume that you don't mean to double-dereference your pointers in the comparator. ie, you should do either:
return (file_1->getFileName() < file_2->getFileName());
or:
return ((*file_1).getFileName() < (*file_2).getFileName());
but not both.