Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: XE8 enterprise, E2336 - Pointer to overloaded function 'function' doesn't



Permlink Replies: 4 - Last Post: Mar 21, 2017 4:34 AM Last Post By: Jan Dijkstra Threads: [ Previous | Next ]
Jan Dijkstra

Posts: 206
Registered: 11/4/99
XE8 enterprise, E2336 - Pointer to overloaded function 'function' doesn't
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 10, 2017 2:24 AM
I have the following declarations (non relevant members left out)

typedef void __fastcall (__closure *TUpdateGuardFunc) (void);
 
class PACKAGE SUpdater
{
protected:
  TUpdateGuardFunc FEndFunc;
 
  __fastcall SUpdater (void);
 
public:
  __fastcall  SUpdater (TUpdateGuardFunc beginFunc, TUpdateGuardFunc endFunc);
  __fastcall  SUpdater (TStrings *strings);
  __fastcall  SUpdater (TCollection *collection);
  __fastcall ~SUpdater (void);
};

and another class
class PACKAGE TLicTranslations : public TLicCustomTextFile
{
...
public:
 
   virtual int   __fastcall  Load (TStrings *source);
 
          void  __fastcall  DisableUpdates (void);
          void  __fastcall  EnableUpdates (void);
          void  __fastcall  Push (UnicodeString const &documentTag, UnicodeString const &languageId);
          void  __fastcall  Push (UnicodeString const &documentTag);
          void  __fastcall  Push (void);
          void  __fastcall  Pop (void);
 
};

In member function Load, I have the following
  SUpdater updater    (DisableUpdates, EnableUpdates);
  SUpdater restoreIds (Push, Pop);

The first of these lines compiles without a problem, but the second one gives an error. With the code as shown above, the error is E2285 Could not find a match for 'SUpdater::SUpdater(void (_fastcall TLicTranslations::*)(const UnicodeString &,const UnicodeString &),void)'

When I change it into
  SUpdater updater    (DisableUpdates, EnableUpdates);
  SUpdater restoreIds ((TUpdateGuardFunc) &Push, Pop);

the error changes into E2336 Pointer to overloaded function 'TLicTranslations::Push' doesn't match 'TUpdateGuardFunc'

My question is why?

The signatures for DisableUpdates and EnableUpdates are exactly the same as for Push and Pop. The only difference is that for Push I have two more overloaded variants. According to

http://webcache.googleusercontent.com/search?q=cache:AO9sGvPv6aAJ:http://en.cppreference.com/w/cpp/language/overloaded_address%2Bc%2B%2B+get+address+overloaded+function&hl=en&gbv=1&ct=clnk

the compiler should pick the overloaded variant that matches the signature. So, why isn't the signature for void __fastcall Push (void) a match, while it is a match for void __fastcall DisableUpdates (void)
Martin van der ...

Posts: 57
Registered: 7/14/02
Re: XE8 enterprise, E2336 - Pointer to overloaded function 'function' doesn't
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 10, 2017 5:43 AM   in response to: Jan Dijkstra in response to: Jan Dijkstra
My question is why?

The signatures for DisableUpdates and EnableUpdates are exactly the same as for Push and Pop. The only difference is that for Push I have two more overloaded variants. According to

http://webcache.googleusercontent.com/search?q=cache:AO9sGvPv6aAJ:http://en.cppreference.com/w/cpp/language/overloaded_address%2Bc%2B%2B+get+address+overloaded+function&hl=en&gbv=1&ct=clnk

the compiler should pick the overloaded variant that matches the signature. So, why isn't the signature for void __fastcall Push (void) a match, while it is a match for void __fastcall DisableUpdates (void)

That's for C++ function pointers, though, and __closure isn't C++ but a compiler extension to support the VCL. I seem to remember that the compiler picks the first function definition it encounters in these cases - so if you swap them around and make the single-parameter version the first one, it could work. Try that.
Jan Dijkstra

Posts: 206
Registered: 11/4/99
Re: XE8 enterprise, E2336 - Pointer to overloaded function 'function' doesn't
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 10, 2017 6:39 AM   in response to: Martin van der ... in response to: Martin van der ...
Martin van der Plas wrote:
My question is why?

The signatures for DisableUpdates and EnableUpdates are exactly the same as for Push and Pop. The only difference is that for Push I have two more overloaded variants. According to

http://webcache.googleusercontent.com/search?q=cache:AO9sGvPv6aAJ:http://en.cppreference.com/w/cpp/language/overloaded_address%2Bc%2B%2B+get+address+overloaded+function&hl=en&gbv=1&ct=clnk

the compiler should pick the overloaded variant that matches the signature. So, why isn't the signature for void __fastcall Push (void) a match, while it is a match for void __fastcall DisableUpdates (void)

That's for C++ function pointers, though, and __closure isn't C++ but a compiler extension to support the VCL. I seem to remember that the compiler picks the first function definition it encounters in these cases - so if you swap them around and make the single-parameter version the first one, it could work. Try that.

Already tried that. Didn't work. I get the same error.
Valence Crearer

Posts: 64
Registered: 11/27/99
Re: XE8 enterprise, E2336 - Pointer to overloaded function 'function' doesn't
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 10, 2017 6:20 AM   in response to: Jan Dijkstra in response to: Jan Dijkstra
... void __fastcall Push (UnicodeString const &documentTag, UnicodeString const &languageId);
void __fastcall Push (UnicodeString const &documentTag);
void __fastcall Push (void);
<snip...>
SUpdater updater (DisableUpdates, EnableUpdates);
SUpdater restoreIds (Push, Pop);
{code}
The first of these lines compiles without a problem, but the second one gives an error. With the code as shown above, the error is E2285 Could not find a match for 'SUpdater::SUpdater(void (_fastcall TLicTranslations::*)(const UnicodeString &,const UnicodeString &),void)'

SUpdater restoreIds(static_cast<void __fastcall(__closure*)(void)>(Push),Pop);
or perhaps
SUpdater restoreIds(static_cast<TUpdateGuardFunc>(Push),Pop);

Use static_cast to tell the compiler to which of the three Push you refer.

For whatever reason, the C++ gods have chosen static_cast as this disambiguation operator.
Jan Dijkstra

Posts: 206
Registered: 11/4/99
Re: XE8 enterprise, E2336 - Pointer to overloaded function 'function' doesn't
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 21, 2017 4:32 AM   in response to: Valence Crearer in response to: Valence Crearer
Valence Crearer wrote:
... void __fastcall Push (UnicodeString const &documentTag, UnicodeString const &languageId);
void __fastcall Push (UnicodeString const &documentTag);
void __fastcall Push (void);
<snip...>
SUpdater updater (DisableUpdates, EnableUpdates);
SUpdater restoreIds (Push, Pop);

The first of these lines compiles without a problem, but the second one gives an error. With the code as shown above, the error is E2285 Could not find a match for 'SUpdater::SUpdater(void (_fastcall TLicTranslations::*)(const UnicodeString &,const UnicodeString &),void)'

SUpdater restoreIds(static_cast<void __fastcall(__closure*)(void)>(Push),Pop);
or perhaps
SUpdater restoreIds(static_cast<TUpdateGuardFunc>(Push),Pop);

Use static_cast to tell the compiler to which of the three Push you refer.

For whatever reason, the C++ gods have chosen static_cast as this disambiguation operator.

Initially, I just solved the problem by making a copy of the Push (void) member with a non overloaded name, and used that.

However, since then I've created a link class that passes the Push and Pop member to the TLicTranslations member stored inside as a private member. Using the same SUpdater class, this time it worked without the compiler giving a peep.

So I went back to the TLicTranslations class and it's Load member, and tried this:

  SUpdater restoreIds (this->Push, this->Pop);

and to my amazement, this works. I no longer get the compiler error on this line. Remove the "this->" bits, and the error is back. Now I'm truly baffled. Inside a member function, it should make absolutely no difference if I refer to another member of the same class with or without the "this->" in front of it, but here clearly it does.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02