Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8081119
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 5, 20262026-06-05T16:37:52+00:00 2026-06-05T16:37:52+00:00

I would like to know if the following code are valid. The original intension

  • 0

I would like to know if the following code are valid.

The original intension is that, I like a base class that dispatch calls to a certain member to either derived class members if it is there or fall back to default behaviors if derived class does not have this member. Another use is that this base class can be used by itself and the Derived template parameter becomes a implementation policy. Anyway, the following MWE compiles and runs correctly with clang++, Intel, icpc and MSVS. However it fails with g++ (from 4.4 to 4.6, any version I had a hand on) with the error message at the end of the question.

If I change the call at point (1), (2), (3) to call_dispatch (which was the sort of thing I did originally), g++ does not complain anymore. I don’t think it is a good practice to have the dispatch function and the caller having the same name. I was just curious if it will work, and curiously enough to try it out (I have no idea how does this idea come to me). My rationale behind this is that, at pint (1), call is invoked with one parameter, so the overload resolution will not match its caller, the zero parameter one. It will not match the SFINAE one at point (2) either, since D2 does not have the member, and then it shall match the one at point (3). Just as in the situation when (1)-(3) are named call_dispatch.

But g++ does not agree with me and other compilers. So, is it an incorrect implementation of g++ or the code itself is invalid? Besides the error message is really confusing. Where does the void (B<D2>::*)() and &B<D2>::call come from? Int he called the member pointer was defined as D2‘s member.

#include <iostream>
#include <functional>

template <typename Derived>
class B
{
    public :

    void call ()
    {
        call<Derived>(0); //----------------------------------------- (1)
    }

    private :

    template <typename D, void (D::*)()> class SFINAE {};

    template <typename D>
    void call (SFINAE<D, &D::call> *) //---------------------------- (2)
    {
        static_cast<Derived *>(this)->call();
    }

    template <typename D>
    void call (...) //--------------------------------------------- (3)
    {
        std::cout << "Call B" << std::endl;
    }
};

class D1 : public B<D1>
{
    public :

    void call ()
    {
        std::cout << "Call D1" << std::endl;
    }
};

class D2 : public B<D2> {};

int main ()
{
    D1 d1;
    D2 d2;
    d1.call();
    d2.call();

    return 0;
}

Error:

foo.cpp: In member function ‘void B<Derived>::call() [with Derived = D2]’:
foo.cpp:48:13:   instantiated from here
foo.cpp:11:9: error: ‘&B<D2>::call’ is not a valid template argument for type ‘void (D2::*)()’ because it is of type ‘void (B<D2>::*)()’
foo.cpp:11:9: note: standard conversions are not allowed in this context

Edit

Though I have not fully understand what goes wrong in the above code yet. But I think there is a another way without specifically construct a SFINAE class but archive the same effect.

#include <iostream>

template <typename Derived>
class B
{
    public :

    void call ()
    {
        call_dispatch(&Derived::call);
    }

    template <typename C>
    void call_dispatch (void (C::*) ())
    {
        static_cast<Derived *>(this)->call();
    }

    void call_dispatch (void (B<Derived>::*) ())
    {
        std::cout << "Call B" << std::endl;
    }

    private :
};

class D1 : public B<D1>
{
    public :

    void call ()
    {
        std::cout << "Call D1" << std::endl;
    }
};

class D2 : public B<D2> {};

int main ()
{
    D1 d1;
    D2 d2;

    d1.call();
    d2.call();

    return 0;
}

Basically, because D1 and D2 both are derived from B, so the expression &Derived::call will always be resolved. In D1 it resolved to &D1::call, then the template version member is used. In D2, it does not have its own call, so &D2::call is resolved to &B::call, and thanks to
@DavidRodríguez-dribeas, who points out that now &D2::call has the type B::call, therefore the template and the non-template members equally match, but non-template is preferred. So the default call is used.

Can help me see if there is any defect in this new code?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-05T16:37:55+00:00Added an answer on June 5, 2026 at 4:37 pm

    Where does the void (B::*)() and &B::call come from?

    The type of a pointer to member is not the type on which you obtained such pointer, but the type on which the member is defined.

    struct base { int x; };
    struct derived : base {};
    int main() {
       std::cout << std::is_same< decltype(&derived::x), int (base::*) >::value << std::endl;
    }
    

    The above program prints 1. In your case, when you use &D::base, the compiler finds B<D2>::call as a member of the base template, and that is the result of the expression: void (B<D2>::*)().

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I would like to know if the following code would be a good pattern
I would like to know if it is safe to use the following code
I would like to know if the following javascript is 'valid' or not. var
I would like to know how I can add the following code to my
With respect to the following code segment, I would like to know whether my
Apparently, the following is the valid syntax: b'The string' I would like to know:
I would like to know if the following code leaks: bool IsWordOf(NSString* myString, NSString*
I would like to know if the following code may ever fail with the
I would like to know if the following code should work: if (M !=
I would like to know how to translate the following code to codebehind instead

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.