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

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 6, 20262026-06-06T22:08:35+00:00 2026-06-06T22:08:35+00:00

I cannot think about a proper question title to describe the problem. Hopefully the

  • 0

I cannot think about a proper question title to describe the problem. Hopefully the details below explains my problem clear.

Consider the following code

#include <iostream>

template <typename Derived>
class Base
{
    public :

    void call ()
    {
        static_cast<Derived *>(this)->call_impl();
    }
};

class D1 : public Base<D1>
{
    public :

    void call_impl ()
    {
        data_ = 100;
        std::cout << data_ << std::endl;
    }

    private :

    int data_;
};

class D2 : public Base<D1> // This is wrong by intension
{
    public :

    void call_impl ()
    {
        std::cout << data_ << std::endl;
    }

    private :

    int data_;
};

int main ()
{
    D2 d2;
    d2.call_impl();
    d2.call();
    d2.call_impl();
}

It will compile and run though the definition of D2 is intentionally wrong. The first call d2.call_impl() will output some random bits which is expected as D2::data_ was not initialized. The second and third calls will all output 100 for the data_.

I understand why it will compile and run, correct me if I am wrong.

When we make the call d2.call(), the call is resolved to Base<D1>::call, and that will cast this to D1 and call D1::call_impl. Because D1 is indeed derived form Base<D1>, so the cast is fine at compile time.

At run time, after the cast, this, while it is truly a D2 object is treated as if it is D1, and the call to D1::call_impl will modified the memory bits that are supposed to be D1::data_, and output. In this case, these bits happened to be where D2::data_ are. I think the second d2.call_impl() shall also be undefined behavior depending on the C++ implementation.

The point is, this code, while intensionally wrong, will give no sign of error to the user. What I am really doing in my project is that I have a CRTP base class which acts like a dispatch engine. Another class in the library access the CRTP base class’ interface, say call, and call will dispatch to call_dispatch which can be base class default implementation or derived class implementation. These all will work fine if the user defined derived class, say D, is indeed derived from Base<D>. It will raise compile time error if it is derived from Base<Unrelated> where Unrelated is not derived from Base<Unrelated>. But it will not prevent user write code like above.

The user use the library by deriving from the base CRTP class and providing some implementation details. There are certainly other design alternatives that can avoid the problem of incorrect use as above (for example an abstract base class). But let’s put them aside for now and just believe me that I need this design because of some reason.

So my question is that, is there any way that I can prevent the user from writing incorrect derived class as see above. That is, if user write an derived implementation class, say D, but he derived it from Base<OtherD>, then a compile time error shall be raised.

One solution is use dynamic_cast. However, that is expansive and even when it works it is a run-time error.

  • 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-06T22:08:36+00:00Added an answer on June 6, 2026 at 10:08 pm

    1) make all constructors of Base private (if there are no constructors, add one)

    2) declare Derived template parameter as friend of Base

    template <class Derived>
    class Base
    {
    private:
    
      Base(){}; // prevent undesirable inheritance making ctor private
      friend  Derived; // allow inheritance for Derived
    
    public :
    
      void call ()
      {
          static_cast<Derived *>(this)->call_impl();
      }
    };
    

    After this it would be impossible to create any instances of the wrong inherited D2.

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

Sidebar

Related Questions

I have read much information about agile and waterfall and I just cannot think
Friends, I have a strange need and cannot think my way through the problem.
I think I might be overtired but I cannot for the life of me
I think you can and my colleage thinks you cannot!
I think I've seen this done once, but I cannot find it again after
I think i already know the answer to this, but i cannot find anything
Excuse the poor title, i can not think of the correct term. I have
I cannot wrap my brain around the following thing ... and I hope there's
I think this is a simple question, but I can not find the answer
Would like to know from all you guys what do you think about my

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.