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 6832209
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T22:49:51+00:00 2026-05-26T22:49:51+00:00

Hi there, While making a CRTP-based generic wrapper to call arbitrary library functions, I’ve

  • 0

Hi there,

While making a CRTP-based generic wrapper to call arbitrary library functions, I’ve encountered a problem which I have trouble understanding. Here is a very simplified code to illustrate the problem:

#include <iostream>

template< typename PValue, typename PDerived >
class TBase
{
 private:
  typedef TBase TSelf_;
  typedef PDerived TDerived_;

 protected:
  typedef PValue TValue_;

 protected:
  TBase( void )
  {
   std::cout << " TBase::TBase() " << std::endl;
  }

 public:
  void Foo( void )
  {
   std::cout << " TBase::Foo() " << std::endl;
  }

  template< typename PType >
  static void Call( PType /*pSomething*/, void(TDerived_::*pFunction)( void ) = &TSelf_::Foo, TDerived_ pDerived = TDerived_() )
  {
   ( pDerived.*pFunction )();
   std::cout << " static TBase::Call(). " << std::endl;
  }
};

template< typename PValue >
class TDerived : public TBase< PValue, TDerived< PValue > >
{
  friend class TBase< PValue, TDerived< PValue > > ;
 private:
  typedef TBase< PValue, TDerived > TBase_;
  typedef TDerived TSelf_;
 public:
  TDerived( void ) :
   TBase_()
  {
   std::cout << " TDerived::TDerived() " << std::endl;
  }
  void Foo( void )
  {
   std::cout << " TDerived::Foo() " << std::endl;
  }
  void Bar( void )
  {
   std::cout << " TDerived::Bar() " << std::endl;
  }
};

int main( void )
{
 TDerived< int >::Call( 1 );
 TDerived< int >::Call( 1, &TDerived< int >::Foo );
 TDerived< int >::Call( 1, &TDerived< int >::Bar, TDerived< int > () );
 return ( 0 );
}

Everything compiles and works as intended. However, if I try to use pointer to TDerived::Foo() as a default argument for the second parameter in TBase::Call(...):

static void Call( PType /*pSomething*/, void(TDerived_::*pFunction)( void ) = &TDerived_::Foo, TDerived_ pDerived = TDerived_() )

compilers gives a syntax error… I have a feeling it is related to how compiler parses code and that it cannot figure out pointer to a function of yet to be defined (or instantiated) class. However, it has no problem calling TDerived constructor as a default argument for the third parameter of TBase::Call(...). Can someone give me a definite answer about what’s going on? Why derived class MFP is not accepted, and object of derived class is accepted as default arguments?

Thanks.

EDIT: compiler’s error (MSVS2010 command line compiler):

FMain.cpp(224) : error C2061: syntax error : identifier 'TDerived_'; FMain.cpp(233) : see reference to class template instantiation 'TBase<PValue,PDerived> with [PValue=int,PDerived=TDerived<int>]' being compiled; FMain.cpp(323) : see reference to class template instantiation 'TDerived<PValue> with [PValue=int]' being compiled

It’s a syntax error – it does not recognize TDerived_ as type in default argument for MFP. There are other errors following this one, they are all syntax errors, since function definition is ill-formed now. That is how I understand it.

EDIT: Basically, I don’t understand why can I use an object of TDerived_ as a default argument, but can not use a pointer to a member function as a default argument.

EDIT: Ok, this is driving me crazy now.
First of all, I changed to typedef TBase< PValue, TDerived > TBase_; as it was pointed out (thank you, guys!). Indeed, it only compiled under MSVC++, since this compiler does not do two-part parsing; i.e., on codepad.org (which uses g++ 4.1.2) it didn’t compile.
Second, after that, I tried to use static void Call( PType /*pSomething*/, void(TDerived_::*pFunction)( void ) = &TDerived_::Foo, TDerived_ pDerived = TDerived_() ) on codepad.org and… it compiled and run correctly! So I’m REALLY confused now: people explained to me why it’s not correct (and I couldn’t understand “why” (see my previous EDIT)) and now it turns out g++ compiles it correctly… Does it mean it just MSVC++ problem and not the code? Or code does have a problem from the Standard point of view (and I cannot see it) and g++ accept it “by mistake” (unlikely, I think)?.. Help?!

  • 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-05-26T22:49:52+00:00Added an answer on May 26, 2026 at 10:49 pm

    The scoping for the TValue_ parameter to the type in the typedef for TBase_ in TDerived appears to be wrong (!)

    You have:

     private:
      typedef TBase< TValue_, TDerived > TBase_;
    

    I think you need:

     private:
      typedef TBase< typename TBase< PValue, TDerived< PValue > >::TValue_, TDerived > TBase_;
    

    Or even just:

     private:
      typedef TBase< PValue, TDerived > TBase_;
    

    EDIT: The C++ standard section 14.6.2 para 3 covers this case:

    In the definition of a class or class template, if a base class
    depends on a template-parameter, the base class scope is not examined
    during unqualified name lookup either at the point of definition of
    the class template or member or during an instantiation of the class
    template or member

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

Sidebar

Related Questions

While making AutoHotkey-script I encountered the following problem. I need navigate listbox (one position
While there are 100 ways to solve the conversion problem, I am focusing on
Is there a way to manually scale a view while making sure the position
i have one problem while making a query wellid dated drillid 1 2000-05-01 11:30:00
I'm having a little problem while making a game, and while the problem is
I am having a strange problem while making an application in iPhone. The problem
I am having a strange problem while making app requests. I understand that when
I use Clearcase on a project with ~3700 files. While making a release, there
While there are many good online and offline tools for testing regular expressions, I
While there are a handful of great programs for ISV Startups (BizSpark, Emplower ISV,

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.