473,320 Members | 1,868 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

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* (*DerivedFuncPtr)();

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(&CreateDerived);
}
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 3387

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* (*DerivedFuncPtr)();

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(&CreateDerived);
}
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* (*DerivedFuncPtr)();

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(&CreateDerived);
}
[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* (*DerivedFuncPtr)();

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*, &CreateDerived> );
}
--
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
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,...
7
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...
12
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...
23
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
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...
3
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...
8
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...
7
by: Arindam | last post by:
#include <cstdio> struct Test { void bar() { foo(); } private: virtual void foo() { printf("Test\n"); }
2
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...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.