473,544 Members | 1,213 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Polymorphic Function Pointers

Hi all,

This is not something I've played around with much, but I'm designing
some factories and I want a function like this:

template<class T>
T* Creator() {
return new T;
}

So that I could store a pointer to an instance in a map along with a
string Id.

Now, the things I want to return would be polymorphic, and so I would
make use of covariant return types. The problem I ran into was
something like the following:

struct Base { virtual ~Base(){} };
struct Derived : Base {};

typedef Base* (*BaseFuncPtr)( );
typedef Derived* (*DerivedFuncPt r)();

Base* CreateBase() { return new Base; }
Derived* CreateDerived() { return new Derived; }

int main()
{
// Covariant return types
Base* b(CreateDerived ());

// Fine
BaseFuncPtr bfp(&CreateBase );

// Cannot convert?
BaseFuncPtr dfp(&CreateDeri ved);
}
Although the function pointers are to different types, the type being
returned is polymorphic and covariant. Can somebody just explain why
this doesn't work? Am I expecting too much?

Cheers for any insights,

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Feb 28 '06 #1
5 3402

I compiled your code with G++ and here's what I got:

g++ creator.cpp -ansi -pedantic -o creator.exe

creator.cpp: In function `int main()':
creator.cpp:19: warning: invalid conversion from `Derived*(*)()' to `Base*
(*)()
It compiled without errors but gave a warning.
Should it give a warning, should it give an error... seems like a quote from
the Standard is in order.
-Tomás
Feb 28 '06 #2
Ben Pope wrote:
This is not something I've played around with much, but I'm designing
some factories and I want a function like this:

template<class T>
T* Creator() {
return new T;
}

So that I could store a pointer to an instance in a map along with a
string Id.

Now, the things I want to return would be polymorphic, and so I would
make use of covariant return types. The problem I ran into was
something like the following:

struct Base { virtual ~Base(){} };
struct Derived : Base {};

typedef Base* (*BaseFuncPtr)( );
typedef Derived* (*DerivedFuncPt r)();

Base* CreateBase() { return new Base; }
Derived* CreateDerived() { return new Derived; }

int main()
{
// Covariant return types
Base* b(CreateDerived ());

// Fine
BaseFuncPtr bfp(&CreateBase );

// Cannot convert?
BaseFuncPtr dfp(&CreateDeri ved);
}
Although the function pointers are to different types, the type being
returned is polymorphic and covariant. Can somebody just explain why
this doesn't work?
WHAT doesn't work? Your attempt to declare a pointer to a function that
takes no args and returns A and initialise it with an address of another
function that takes no args and returns B? They are of different types.
Unrelated.

B func(); // 'func' is a function that takes no args and returns B
A (*pf)() = func; // 'pf': ptr to a func, no args, returns A
// *cannot* be initialised with _anything_ except
// another func that takes no args, returns A

Covariance applies _only_ to virtual functions, and not pointers to
functions.
Am I expecting too much?


Absolutely.

V
--
Please remove capital As from my address when replying by mail
Feb 28 '06 #3
Tomás wrote:
I compiled your code with G++ and here's what I got:

g++ creator.cpp -ansi -pedantic -o creator.exe

creator.cpp: In function `int main()':
creator.cpp:19: warning: invalid conversion from `Derived*(*)()' to `Base*
(*)()
It compiled without errors but gave a warning.
Should it give a warning, should it give an error... seems like a quote from
the Standard is in order.


From 4.3: "An lvalue of function type T can be converted to an rvalue
of type “pointer to T.” The result is a pointer to the function."

Since return value type is part of the function type, if functions have
different return value types, their respective types T1 and T2 are
different, hence a function of type T1 cannot be converted to a pointer
to [function type] T2.

V
--
Please remove capital As from my address when replying by mail
Feb 28 '06 #4
Victor Bazarov wrote:
Covariance applies _only_ to virtual functions, and not pointers to
functions.


Yes, I have just realised that this is the difference between
overloading and overriding.
> Am I expecting too much?


Absolutely.


Of course.

Thanks Victor.

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
Feb 28 '06 #5
* Victor Bazarov:
Ben Pope wrote:

struct Base { virtual ~Base(){} };
struct Derived : Base {};

typedef Base* (*BaseFuncPtr)( );
typedef Derived* (*DerivedFuncPt r)();

Base* CreateBase() { return new Base; }
Derived* CreateDerived() { return new Derived; }

int main()
{
// Covariant return types
Base* b(CreateDerived ());

// Fine
BaseFuncPtr bfp(&CreateBase );

// Cannot convert?
BaseFuncPtr dfp(&CreateDeri ved);
}
[snip] Am I expecting too much?


Absolutely.


Unfortunately, yes. One would expect standard C++ to support this, and
there is no technical reason I'm aware why it couldn't. But it doesn't.

The support for covariance in C++ is half-baked, and there is no support
for contravariance -- we lack data flow direction designators such as
C# and Ada 'out'.

Although there is the general problem of argument forwarding, for a
given function of known signature something like the following can be a
practical solution:

struct Base { virtual ~Base(){} };
struct Derived : Base {};

typedef Base* (*BaseFuncPtr)( );
typedef Derived* (*DerivedFuncPt r)();

Base* CreateBase() { return new Base; }
Derived* CreateDerived() { return new Derived; }

template< typename R, R (*foo)() >
inline Base* asBaseFunction( ) { return foo(); }

int main()
{
// Covariant return types
Base* b(CreateDerived ());

// Fine
BaseFuncPtr bfp(&CreateBase );

// Cannot convert?
BaseFuncPtr dfp( &asBaseFunction <Derived*, &CreateDeriv ed> );
}
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Feb 28 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
2191
by: verec | last post by:
One problem I've come accross in designing a specific version of auto_ptr is that I have to disntiguish between "polymorphic" arguments and "plain" ones, because the template has to, internally, cast to void *. Specifically, template <typename T> void f(T * t) { void * p = dynamic_cast<void *>(t) ; } will not compile if T isn't of a...
7
3901
by: Mr. Ed | last post by:
I have a base class which has about 150 derived classes. Most of the derived classes are very similar, and many don't change the base class at all. All the derived classes have a unique factory method which returns a new object of the derived type. The problem I've got is that I now need to polymorphically clone a derived class object, but...
12
1422
by: Bob | last post by:
Hi, 'Shadowed' properties are not polymorphic. (See thread 'Inheritance and late binding') They should be. Problem: Base class has read only property 'X'. Derived class must have read / write property 'X'. Can't override Base class 'X' because of different structure. So you Shadow the base class 'X' in the derived class. Pass an instance...
23
2490
by: Randy | last post by:
Since these operators can't be member functions, and since friend functions can't be declared virtual, how do I make my inserters and extractors polymorphic? --Randy Yates
5
2768
by: FefeOxy | last post by:
Hi, > I'm having a debug assertion error within the file dbgdel.cpp with the expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) I traced the origin of the error and it happened as I tried to delete a polymorphic class as follows:
3
1625
by: Daniel Kraft | last post by:
Hi, I usually program in C++, but for a special project I do have to code in C (because it may be ported to embedded-like platforms where no C++ compiler exists). I do want to realize some kind of polymorphic behaviour, like this: I have some abstract base "class" Base, that is, a struct containing a vtable of function-pointers and...
8
1638
by: Angelwings | last post by:
Hi everyone, I've to write my own definition of a BST with polymorphic data, as an university course project. I have troubles about comparing data when it's defined as polymorphic pointer. In my situation I've something like: class A {} class B : public A {} class C : public A {}
7
1612
by: Arindam | last post by:
#include <cstdio> struct Test { void bar() { foo(); } private: virtual void foo() { printf("Test\n"); }
2
2617
by: L. Kliemann | last post by:
* Jerry Coffin <jcoffin@taeus.com>: My question was mostly out of curiosity. I've been working with C++ for about half a year now, and I came across several occasions where my first approach was to use polymorphism, but it did not work (could not write compilable code that would express what I meant). In many of these cases, using...
0
7610
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7774
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7381
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
5914
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5299
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
4920
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3418
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3412
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1843
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.