c++ how pass a this pointer conditionally if in member function - c++

When being a) in a c++ free function or b) in a class' member function:
How can i pass a) nullptr respecively b) the this to a generic macro that should work for both?
I know, we shouldn't use macros - but i have legacy code. Maybe later the macro can be replaced. But i think the question remains the same: How to detect if a) in c++ free function or b) in a class' member function and as a consequence use a) nullptr or b) this ptr for processing?
#include <iostream>
#define MYMACRO \
{ \
if (1) { /* what to use here? */ \
std::cout << "MYMACRO used in a member function of class this ptr = " << "" /* print this here */ << std::endl; \
} \
else { \
std::cout << "MYMACRO used in a free function" << std::endl; \
} \
}
struct MyStruct
{
MyStruct() = default;
~MyStruct() = default;
void SomeMemberFunction(void)
{
MYMACRO;
}
};
void SomeFreeFunction(void)
{
MYMACRO;
}
int main(int, char**)
{
MyStruct myStruct;
myStruct.SomeMemberFunction();
SomeFreeFunction();
return 0;
}
i.e. nullptr or this ptr should be detected within the MYMACRO.
Addendum #1
Some comments below asked for purpose - in concrete from #Nicol Bolas. Imagine MYMACRO has some functionality already but shall be extended to additionally provide a new logging function (optionally). When MYMACRO is used for a member function the class name and this ptr value will be logged for tracing and correlation. Just as an example. Then MYMACRO for this needs to know if used in a context of a class member function or not (i.e. if some this ptr is available or not).
Talking in general: it's about "reflection"

If you don't mind inheriting an interface class for any class that needs to invoke your macro, you can take the following approach:
template <class T>
void DoSomething(T* ptr, SomeVar x)
{
std::cout << "Doing something with ptr=" << ptr << "\n";
}
void MYMACRO(SomeVar x)
{
DoSomething<void>(nullptr, x);
}
Note that I will use "MYMACRO" simply as a reference to the part of your program that does the work. It is obviously NOT a macro! Instead, it's just a function that will invoke DoSomething with a NULL pointer.
In order to overload this behavior in classes, you must define an interface:
class SomethingDoer
{
protected:
void MYMACRO(SomeVar x)
{
DoSomething(this, x);
}
};
And then, any class that needs to invoke it should inherit this interface. When a method of that class calls MYMACRO, it will use SomethingDoer::MYMACRO instead of the other function.
class SomeClass : public SomethingDoer
{
public:
bool MemberFunc();
};
bool SomeClass::MemberFunc()
{
SomeVar x;
MYMACRO(x);
return false;
}
If your macro does other stuff as well that is more convenient to use macros for, that's fine. You can still implement as a macro, but have the "this"-related stuff use the mechanism I described.
And if you really need the type of this to be correct, a small adjustment is:
template <class T>
class SomethingDoer
{
protected:
void MYMACRO(SomeVar x)
{
DoSomething((T*)this, x);
}
};
class SomeClass : public SomethingDoer<SomeClass>
{
public:
bool MemberFunc();
};

For free-standing function there is no this, so that part of question doesn't make sense. If you're meaning how to check if local variable x is valid, that's pointless. It's always valid and within its methods this would not be nullptr unless your code boke something. horribly (e.g. somehow broke stack from other thread).
Macro definitions simply replace code, so if you can write
bool SomeClass::MemberFunc(void)
{
if(!this) return;
doSomething();
}
you can write
#define CHECK_THIS if(!this) return
bool SomeClass::MemberFunc(void)
{
CHECK_THIS;
doSomething();
}
Macro unwrapping happens before compilation, preprocessor doesn't analyze your code, so you cannot change macro content contextually.
I.e. it must happen in code.
One "dirty" way is to define some global function which would have local counterpart in every object. In that case any method of object that doesn't contain that definition, would behave as there is no this.
It can be done by inheritance, like paddy had shown in his answer, or another macro in class body:
// global MYMACRO for free fuctions.
void MYMACRO () {};
#define DECLARE_MYMACRO \
void MYMACRO () { \
if(!this) doSomething(); \
}
class MyClass {
DECLARE_MYMACRO
public:
void memberFunc(void);
};
Is as a rule, check if this is nullptr is a paranoid AND useless effort. You may try that for debugging purposes only, but you cannot use that to create falsely "rugged" code. Thing is a call to member function with null pointer to class-type instance is Undefined Behaviour. The compiler is free to assume that Undefined Behavior didn't happen. So, on practice, a compiler may just throw that if out, because this cannot be nullptr within defined behaviour borders. That's not hypothetical, popular compilers do that when optimization is on.
The check if the address of object is nullptr must happen before the very first use of its member in particular scope, i.e. outside of member. After first use or call gloves are off, the check makes no sense.

this does half the job for c++17
This approach does not work, because __PRETTY_FUNCTION__ also has ':' for a free function that is nested in a namespace. (see comment from Nicol Bolas below - thanks Nicol!)
#include <string_view>
#include <iostream>
constexpr bool ContainsColon(std::string_view str)
{
return str.find(':') != str.npos;
}
#define MYMACRO \
{ \
if constexpr(ContainsColon(__PRETTY_FUNCTION__)) { \
constexpr void *ptr = nullptr; /* still todo */ \
std::cout << "MYMACRO used in a member function of class this ptr = " << (long)ptr << std::endl; \
} \
else { \
std::cout << "MYMACRO used in a free function" << std::endl; \
} \
}
struct MyStruct
{
MyStruct() = default;
~MyStruct() = default;
void SomeMemberFunction(void)
{
MYMACRO;
}
};
void SomeFreeFunction(void)
{
MYMACRO;
}
namespace TestSpace {
void SomeOtherFreeFunction(void)
{
MYMACRO;
}
} // namespace TestSpace
int main(int, char**)
{
MyStruct myStruct;
myStruct.SomeMemberFunction();
SomeFreeFunction();
// ERROR! - this also reports to be called from a member function :-(
TestSpace::SomeOtherFreeFunction();
return 0;
}
output:
MYMACRO used in a member function of class this ptr = 0
MYMACRO used in a free function
MYMACRO used in a member function of class this ptr = 0 # WRONG HERE!

I think you best bet is doing something like this:
#include <type_traits>
#include <iostream>
#define DECLARE_GETTHIS() auto get_this() {return this;}
#define MYMACRO() log_this(get_this())
void *get_this() {return nullptr;}
template<typename T>
void log_this(T *_this) {
if constexpr (std::is_void_v<T>) {
std::cout << "We are in freestanding function" << std::endl;
} else {
std::cout << "We are in class function, this: " << _this << std::endl;
}
}
struct S {
DECLARE_GETTHIS();
void func() {
MYMACRO();
}
};
int main() {
MYMACRO();
S s;
s.func();
}
Of course for this to work you will need to insert DECLARE_GETTHIS(); in ALL base classes. But I don't see any other ways without some modifications in classes.
Declaration of global get_this() can be placed in same header where MYMACRO() is defined with inline specifier.
Also, constexpr can be dropped in if constexpr if you need this to work for older versions.

Related

using pointer to inline function vs using pointer to function

I want to pass pointers of some functions to a template class to use them later. I was wondering if:
Does it make a possibly (speed-wise) beneficial difference if I make these functions inline?
Functions themselves are possibly one line wrapper for another functions like the example below:
//inline ?
void func_wrapper_1(){
func1(arg1);
}
//inline ?
void func_wrapper_2(){
func2(arg2);
}
and the class template is like the example below:
template<void(*f1)(), void(*f2)()>
class caller{
public:
static void func(int v){
if(v) {
(*f1)();
}else{
(*f2)();
}
}
};
And later on in the main function it will be used like the example below:
caller<func_wrapper_1,func_wrapper_2>::func(0);
caller<func_wrapper_1,func_wrapper_2>::func(1);
I know that every things depends on compiler and compiling option, but lets assume compiler accepts to make these functions inline.
Whether or not a compiler will be smart enough to inline a given situation is up for grabs but I think it may be possible by creating Callable Types by overloading the function call operator.
Something like this:
template<typename Func1, typename Func2>
class caller{
public:
static void func(int v){
if(v) {
// Func1() - creates an object of type Func1
// that object is 'called' using the '()' operator
Func1()();
}else{
Func2()();
}
}
};
struct CallableType1
{
// overloading the function call operator makes objects of
// this type callable
void operator()() const { std::cout << "callable 1" << '\n'; }
};
struct CallableType2
{
void operator()() const { std::cout << "callable 2" << '\n'; }
};
int main()
{
caller<CallableType1, CallableType2> cc;
cc.func(2);
}

Is it safe to cast between a function pointer and a member function pointer? [duplicate]

I've inherited some C++ code and I've been tasked with getting rid of warnings.
Here we have a member function pointer being cast to a function pointer.
I understand that member function pointers are "different" from function pointers, in that there is an implicit 'this' parameter involved under the hood. However my predecessor appears to have made explicit use of this fact, by casting from a member function pointer to a function pointer with an additional first parameter inserted.
My Questions are:
A) Can I get rid of the compiler warning?
B) To what extent is this code guaranteed to work?
I've cut it down to a small main.cpp for the purposes of this question:
#define GENERIC_FUNC_TYPE void(*)(void)
#define FUNC_TYPE int(*)(void *)
class MyClass
{
public:
MyClass(int a) : memberA(a) {}
int myMemberFunc()
{
return memberA;
}
private:
int memberA;
};
int main(int argc, char*argv[])
{
int (MyClass::* memberFunc) () = &MyClass::myMemberFunc;
MyClass myObject(1);
std::cout << (myObject.*memberFunc)() << std::endl;
// All good so far
// Now get naughty, store it away in a very basic fn ptr
void(*myStoredFunction)(void) = (GENERIC_FUNC_TYPE)memberFunc; // Compiler warning
// Reinterpret the fn pointer as a pointer to fn, with an extra object parameter
int (*myExtractedFunction)(void*) = (FUNC_TYPE)myStoredFunction;
// Call it
std::cout << myExtractedFunction(&myObject) << std::endl;
}
The code compiles with one warning under g++, and as intended outputs two 1's:
main.cpp: In function ‘int main(int, char**)’:
main.cpp:27:53: warning: converting from ‘int (MyClass::*)()’ to ‘void (*)()’ [-Wpmf-conversions]
void(*myStoredFunction)(void) = (GENERIC_FUNC_TYPE)memberFunc; // Compiler warning
^
IMHO this code is making assumptions about the underlying mechanisms of the compiler. Or maybe these assumptions are valid for all C++ compilers - Can anyone help?
(In the actual code we're storing a whole bunch of function pointers by name in a map. These functions all have different signatures, which is why they are all cast to the same signature void(*)(void). This is analogous to the myStoredFunction above. They are then cast to the individual signatures at the point of calling, analogous to myExtractedFunction above.)
How about create functions which avoid the cast entirely:
template <typename C, void (C::*M)()>
void AsFunc(void* p)
{
(static_cast<C*>(p)->*M)();
}
then
void (*myExtractedFunction)(void*) = &AsFunc<MyClass, &MyClass::myMemberFunc>;
In C++17, with some traits, you might even have template <auto *M> void AsFunc(void* p) and void(*myStoredFunction)(void*) = &AsFunc<&MyClass::myMemberFunc>;
To answer the question in the title, no, you can't legally cast a pointer-to-member-function to a pointer-to-function. Presumably, that's what the "Compiler warning" on the line with that cast said.
A conforming compiler is required to issue a diagnostic when confronted with ill-formed code (that's a bit oversimplified), and this one did. It gave a warning. Having done that, the compiler is free to do something implementation-specific, which it seems to have done: it compiled the code into something that does what you were hoping for.
Compilers are free to represent pointers to member functions in any way that works, and for non-virtual functions, that could be just a "normal" pointer to function. But try that with a virtual function; I'll bet the consequences are more harsh.
A) Can I get rid of the compiler warning?
Yes - wrap the member function in a call from a static function
(This is a low-tech variant of #Jarod42's template based answer)
B) To what extent is this code guaranteed to work?
It's not (summarizing #Pete Becker's answer). Until you get rid of the warning.
Here's the jist of what we went with. We kept it simple to minimize disruption to the code. We avoided advanced C++ features to maximize the number of people who can work on the code.
#include <iostream>
class MyClass
{
public:
MyClass(int a) : memberA(a) {}
static int myMemberFuncStatic(MyClass *obj)
{
return obj->myMemberFunc();
}
int myMemberFunc()
{
return memberA;
}
private:
int memberA;
};
typedef void(*GENERIC_FUNC_TYPE)(void);
typedef int(*FUNC_TYPE)(MyClass *);
int main(int argc, char*argv[])
{
int (* staticFunc) (MyClass *) = &MyClass::myMemberFuncStatic;
MyClass myObject(1);
std::cout << staticFunc(&myObject) << std::endl;
// All good so far
// This is actually legal, for non-member functions (like static functions)
GENERIC_FUNC_TYPE myStoredFunction = reinterpret_cast<GENERIC_FUNC_TYPE> (staticFunc); // No compiler warning
// Reinterpret the fn pointer as the static function
int (*myExtractedFunction)(MyClass*) = (FUNC_TYPE)myStoredFunction;
// Call it
std::cout << myExtractedFunction(&myObject) << std::endl;
}
Since you apparently need to call a function by name on some "untyped" object (void*) while passing in a number of arguments that differ by function, you need some kind of multiple-dispatch. A possible solution is:
#include <string>
#include <iostream>
#include <stdexcept>
#include <functional>
#include <utility>
#include <map>
template <typename Subj>
using FunctionMap = std::map<std::string, std::function<void (Subj&, const std::string&)>>;
class AbstractBaseSubject {
public:
virtual void invoke (const std::string& fName, const std::string& arg) = 0;
};
template <typename Class>
class BaseSubject : public AbstractBaseSubject {
public:
virtual void invoke (const std::string& fName, const std::string& arg) {
const FunctionMap<Class>& m = Class::functionMap;
auto iter = m.find (fName);
if (iter == m.end ())
throw std::invalid_argument ("Unknown function \"" + fName + "\"");
iter->second (*static_cast<Class*> (this), arg);
}
};
class Cat : public BaseSubject<Cat> {
public:
Cat (const std::string& name) : name(name) {}
void meow (const std::string& arg) {
std::cout << "Cat(" << name << "): meow (" << arg << ")\n";
}
static const FunctionMap<Cat> functionMap;
private:
std::string name;
};
const FunctionMap<Cat> Cat::functionMap = {
{ "meow", [] (Cat& cat, const std::string& arg) { cat.meow (arg); } }
};
class Dog : public BaseSubject<Dog> {
public:
Dog (int age) : age(age) {}
void bark (float arg) {
std::cout << "Dog(" << age << "): bark (" << arg << ")\n";
}
static const FunctionMap<Dog> functionMap;
private:
int age;
};
const FunctionMap<Dog> Dog::functionMap = {
{ "bark", [] (Dog& dog, const std::string& arg) { dog.bark (std::stof (arg)); }}
};
int main () {
Cat cat ("Mr. Snuggles");
Dog dog (7);
AbstractBaseSubject& abstractDog = dog; // Just to demonstrate that the calls work from the base class.
AbstractBaseSubject& abstractCat = cat;
abstractCat.invoke ("meow", "Please feed me");
abstractDog.invoke ("bark", "3.14");
try {
abstractCat.invoke ("bark", "3.14");
} catch (const std::invalid_argument& ex) {
std::cerr << ex.what () << std::endl;
}
try {
abstractCat.invoke ("quack", "3.14");
} catch (const std::invalid_argument& ex) {
std::cerr << ex.what () << std::endl;
}
try {
abstractDog.invoke ("bark", "This is not a number");
} catch (const std::invalid_argument& ex) {
std::cerr << ex.what () << std::endl;
}
}
Here, all classes with functions to be called this way need to derive from BaseSubject (which is a CRTP). These classes (here: Cat and Dog, let's call them "subjects") have different functions with different arguments (bark and meow - of course more than one function per subject is possible). Each subject has its own map of string-to-function. These functions are not function pointers, but std::function<void (SubjectType&,const std::string&)> instances. Each of those should call the respective member function of the object, passing in the needed arguments. The arguments need to come from some kind of generic data representation - here, I chose a simple std::string. It might be a JSON or XML object depending on where your data comes from. The std::function instances need to deserialize the data and pass it as arguments. The map is created as a static variable in each subject class, where the std::function instances are populated with lambdas. The BaseSubject class looks up the function instance and calls it. Since the subject class should always directly derive from BaseSubject<Subject>, pointers of type BaseSubject<Subject>* may be directly and safely cast to Subject*.
Note that there is no unsafe cast at all - it is all handled by virtual functions. Therefore, this should be perfectly portable. Having one map per subject class is typing-intensive, but allows you to have identically-named functions in different classes. Since some kind of data-unpacking for each function individually is necessary anyways, we have individual unpacking-lambdas inside the map.
If a function's arguments are just the abstract data structure, i.e. const std::string&, we could leave the lambdas out and just do:
const FunctionMap<Cat> Cat::functionMap = {
{ "meow", &Cat::meow }
};
Which works by way of std::functions magic (passing this via the 1st argument), which, in contrast to function pointers, is well-defined and allowed. This would be particularly useful if all functions have the same signature. In fact, we could then even leave out the std::function and plug in Jarod42's suggestion.
PS: Just for fun, here's an example where casting a member-function-pointer to an function-pointer fails:
#include <iostream>
struct A {
char x;
A () : x('A') {}
void foo () {
std::cout << "A::foo() x=" << x << std::endl;
}
};
struct B {
char x;
B () : x('B') {}
void foo () {
std::cout << "B::foo() x=" << x << std::endl;
}
};
struct X : A, B {
};
int main () {
void (B::*memPtr) () = &B::foo;
void (*funPtr) (X*) = reinterpret_cast<void (*)(X*)> (memPtr); // Illegal!
X x;
(x.*memPtr) ();
funPtr (&x);
}
On my machine, this prints:
B::foo() x=B
B::foo() x=A
The B class shouldn't be able to print "x=A"! This happens because member-function pointers carry an extra offset that is added to this before the call, in case multiple inheritance comes into play. Casting loses this offset. So, when calling the casted function pointer, this automatically refers to the first base object, while B is the second, printing the wrong value.
PPS: For even more fun:
If we plug in Jarod42's suggestion:
template <typename C, void (C::*M)(), typename Obj>
void AsFunc (Obj* p) {
(p->*M)();
}
int main () {
void (*funPtr) (X*) = AsFunc<B, &B::foo, X>;
X x;
funPtr (&x);
}
the program correctly prints:
B::foo() x=B
If we look at the disassembly of AsFunc, we see:
c90 <void AsFunc<B, &B::foo, X>(X*)>:
c90: 48 83 c7 01 add $0x1,%rdi
c94: e9 07 ff ff ff jmpq ba0 <B::foo()>
The compiler automatically generated code that adds 1 to the this pointer, such that B::foo is called with this pointing to the B base class of X. To make this happen in the AsFunc function (opposed to buried within main), I introduced the Obj template parameter which lets the p argument be of the derived type X such that AsFunc has to do the adding.

How can I overload a member function from an instance of a class

I want to make a class where there is a function that is called automatically, to process information stored within this classes instance.
However each instance has different values and possibly a different way for that content to be handeled.
Therefore I need something simmilar to constructor overloading but in a member function. Where every instance can overload the default function or leave it up to the default to handle the input.
How can that be achieved?
Try to Call Functions in Constructor with if else condition
like:
class abc{
abc(){
if username == "member 1"
functioncall();
else
functioncall();
}
}
As far as I see you need some virtual construction emulation. There is a simple C/C++ way to do it.
// Example program
#include <iostream>
#include <string>
struct A;
typedef void (*cb)(A*);
struct A
{
int m_a;
static void foo(A* aref)
{
std::cout << "Print a: " << aref->m_a << "\n";
}
A(cb b=foo)
{
m_a = 100;
b(this);
}
};
int main()
{
A a;
}
It is not very clear, but still does the trick.
By creating a separate class for the variable behavior Callable describes the local data relating to the function, and by being a class, can be derived.
class Callable {
public:
int m_Value;
Callable(int value) : m_Value(value)
{
}
void operator()( int val1, double val2 /* whatever makes sense */ ) {
}
};
Using the function operator void operator()( ...... ) we create a way of making variables of type Callable to look like a function.
class Variable {
public:
Callable myFunction;
Variable(const Callable & howToCall, /* some more stuff */) :
myFunction(howToCall)
{ /* stuff */
}
void aFunction(int data, double value ) {
myFunction( data, value);
}
};
When calling aFunction the current value of myFunction is called.
Finally Variable can change which function it calls, by modifying the value of myFunction....
myFunction = Callable( /* new parameters */ );

Passing a class method as function argument

I am trying to send a method of a specific class instance as an argument to a function (foo), although I keep getting this error
invalid use of non-static member function...
(from the line foo(a->bar))
I'm not sure why do I get this error? Is there a possible work-around for it?
#include <iostream>
#include <functional>
void foo(std::function<void(void)> _func)
{
_func();
}
class A
{
public:
A()
{
x = 5;
}
void bar()
{
std::cout << x << std::endl;
}
private:
int x;
};
int main() {
A a;
foo(a->bar);
return 0;
}
You have two options:
Use std::bind: foo(std::bind(&A::bar, a)):
Use lambdas: foo([&a]() { a.bar(); });
Your method isn't compatible to std::function, even it looks like.
Every method has an implicit first argument, this.
So your signature looks like this
void bar(A* this) { /* ... */ }
This is not the case for static methods. These are like functions within the namespace of the class and
static void bar() { /* ... */ }
Will saturate std::function.
Still, using a lambda (c++11) is most likely the better way for ur example.

Forcing late method resolution in case of class inheritance in c++

Consider the following class structure:-
class foo {
public:
int fun () {
cout << "in foo" << endl;
}
};
class bar_class1:public foo {
public:
int fun () {
cout << "in bar_class1" << endl;
}
};
class bar_class2:public foo {
public:
float fun () {
cout << "in bar_class2" << endl;
}
};
main () {
foo * foo_pointer = new bar_class1();
foo_pointer->fun();
}
The output of the above program is in foo. Is there a way, that using a pointer of type foo * which actually points to an object of type bar_class1 or bar_class2, we can call the fun function of the derived class instead of the base class? I am not able to make the fun function virtual in the base class foo since, then there is a return type conflict for function foo in the derived class bar_class2.
Here's my comments as an answer.
You cannot do that.
If that kind of polymorphism were possible, wouldn't that break horribly when code calls foo::fun (expecting an int) on an object whose actual type is bar_class2 and thus gets a float? Do you want to simply throw away type safety?
If you want different return types, sounds like you want a template. But you cannot use templates quite in the way that you want to use foo(). Static polymorphism (templates) and run time polymorphism (late binding) don't mix well. You need to redesign your oop structure.
If you absolutely hate type safety, you can sort of do this with void pointers. But for the love of Flying Spaghetti Monster, don't ever do this in c++. Please close your eyes before reading the following code to avoid exposure.
#include <iostream>
class foo {
public:
virtual void* fun() = 0;
virtual ~foo(){};
};
class bar_class1: public foo {
public:
void* fun() {
return &value;
}
private:
int value = 1;
};
class bar_class2: public foo {
public:
void* fun() {
return &value;
}
private:
float value = 1.1;
};
int main() {
foo* foo_pointer1 = new bar_class1();
foo* foo_pointer2 = new bar_class2();
// in c++ compiler must know the type of all objects during compilation
std::cout << *reinterpret_cast<int*>(foo_pointer1->fun()) << '\n';
std::cout << *reinterpret_cast<float*>(foo_pointer2->fun()) << '\n';
delete foo_pointer1;
delete foo_pointer2;
}
Perhaps similar to the existing answer, I really hope you realize changing your design is better than this mess, but I believe it's the best you're going to get. I force you to specify the return type at the callsite (e.g., someFoo->fun<int>()), since you're going to have to know it anyway, and dispatch based on that. Any funny business and you'll get an exception. Also keep in mind the performance of this is, I imagine, less than desirable.
#include <cassert>
#include <stdexcept>
#include <type_traits>
struct foo {
virtual ~foo() = default;
template<typename T, typename = typename std::enable_if<std::is_same<T, int>::value>::type, typename = void>
T fun();
template<typename T, typename = typename std::enable_if<std::is_same<T, float>::value>::type>
T fun();
};
struct bar_class1 : foo {
int fun() {
return 2;
}
};
struct bar_class2 : foo {
float fun() {
return 3.5f;
}
};
template<typename T, typename, typename Dummy>
T foo::fun() {
if (auto *p = dynamic_cast<bar_class1 *>(this)) {
return p->fun();
} else if (dynamic_cast<bar_class2 *>(this)) {
throw std::invalid_argument("Mismatching dynamic type.");
} else {
return 1;
}
}
template<typename T, typename>
T foo::fun() {
auto *p = dynamic_cast<bar_class2 *>(this);
if (dynamic_cast<bar_class1 *>(this) || !p) {
throw std::invalid_argument("Mismatching dynamic type.");
} else if (auto *p = dynamic_cast<bar_class2 *>(this)) {
return p->fun();
}
assert(false); //should never get here, but compiler doesn't know that
}
If you'd like the main function, I've written a complete sample.
To answer your question: No, late binding isn't possible without deciding the return type. ...at least not in a reasonable manner, see user2079303's great counter-example. But...
you may change your code (for example) into something like the following, using the keyword virtual and equalize the return type for instance to void:
class foo
{
public:
virtual void fun(std::ostream& out) {
out << "in foo" << std::endl;
}
};
so you can decide the output type later:
class intFoo: public foo
{
public:
void fun(std::ostream& out) {
// output an int
out << "in bar_class1. data: " << data << endl;
}
int data;
};
class floatFoo: public foo
{
public:
void fun(std::ostream& out) {
// output a float
out << "in bar_class2. data: " << data << endl;
}
float data;
};
For brevity, I double-use the output stream - now a parameter of the function fun() - function to demonstrate type-dependent portion of your derived class. In your application, the parameter will probably be of another, more useful type.
The function fun is not a virtual function since you didn't use the keyword "virtual" to decorate it. So, the compile will determine which function to call at compiling time. So, there is no way to tell the compiler to call another function because the compiler will use its static type, i.e. the variable definition type -- foo *.