#Private methods with CRTP

39 messages · Page 1 of 1 (latest)

quick orchid
#

are there any tricks to override private or protected methods in a base class with CRTP without changing visibility

template<typename Derived>
class Base {
    void foo() { std::cout << "Base::foo\n"; static_cast<Derived*>(this)->foo(); } // private

public:
    void bar() { this->foo(); } // part of the public interface
};

class Derived : public Base<Derived> {
    void foo() { std::cout << "Derived::foo\n"; } // override, still private to match visibility of base interface
};

int main() {
    Derived d{};
    d.bar(); // error : 'foo' is a private member of 'Derived'
}```

I'm trying to essentially achieve what would otherwise be overriding a private virtual method with CRTP. but of course this doesnt work. I've seen similar-ish SO articles on this topic but the solutions are very complex and not so ideal: https://stackoverflow.com/a/55928800

I was wondering if there were any hidden tricks to achieve this functionality
bright juniperBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

autumn vortex
#

make Base<Derived> a friend of Derived

quick orchid
#

well, this works well in the simple example I provided, but my real use case is a thousand lines long and heavly templated . i know this isnt very helpful for anyone to diagnose but ive been pulling my hair out trying to figure out what this even means :/ (its own class cant access a private member?)

#

ill try and isolate the problem with my current codebase

thin dome
quick orchid
#

ideally the bot should detect that i still want to compile that code even tho i said something above it^

quick orchid
thin dome
#

you're not friending the righ thing

quick orchid
#

oh ok...i cant understand why the friend Base in my 2nd example is any different than the friend Base<Derived> which would be the correct solution to the 1st

#

what should the right thing be?

thin dome
#

or depending on how you wish to solve this, the intermediate class that is being friend'ed has to give access down to the class that actually wants the access

quick orchid
#

why is it that calling foo through an IntSetting works, but not through a VisualIntSetting?

thin dome
#

because you have an extra intermediate in between

#

that's the whole thing I was just talking about

quick orchid
#

ok, I think I see what you mean

thin dome
#

IntSettingCommon<ISetting<IntSetting>> has ISetting<IntSetting> as friend, and ISetting<IntSetting> tries to use the private member of the first one so it works

IntSettingCommon<IVisualSetting<VisualIntSetting>> has IVisualSetting<VisualIntSetting> as friend but IVisualSetting<VisualIntSetting> never does anything, the part that wants to get into the private is ISetting<VisualIntSetting>

quick orchid
#

yesss ok

thin dome
#

also semi mandatory mention that I don't encourage the use of _isDirty but that's technically legal in that context

quick orchid
fierce orbitBOT
#
Program Output
1
1
quick orchid
#

regarding the visibility issue, what do you think abt this? in practice I'd have a type constraint for what can inherit from IntSettingCommon (such that Base must also inherit from ISetting)

thin dome
quick orchid
#

oh you just take issue with the _

#

yea tru

thin dome
#

names beginning with lowercase are generally annoying and if you're in a context where there's even a single person who doesn't know when it is forbidden, it's just better to forbid them completely, is my general stance

#

in the wild you'll see any number of variations like DoFoo FooImpl in any casing convention you can think of

quick orchid
#

would you say that an appropriate renaming for _isDirty should indicate that it is the actual implementation? i.e. isDirtyImpl

thin dome
# quick orchid regarding the visibility issue, what do you think abt this? in practice I'd have...

regarding the visibility issue, what do you think abt this?
well it works, but depending on what your exact context is it's hard to say if that's for the best or not
in particular it's a bit fuzzy whether some of the things would want to know about the direct derived class, the most derived one, or both

in practice I'd have a type constraint for what can inherit from IntSettingCommon (such that Base must also inherit from ISetting)
depending on how exactly you set up things you may end up with weird circularities, so be careful about that

thin dome
thin dome
quick orchid
#

in particular it's a bit fuzzy whether some of the things would want to know about the direct derived class, the most derived one, or both
i could just make the type alias protected. but i dont know what u mean by "fuzzy"

quick orchid
#

!solved

bright juniperBOT
#

Thank you and let us know if you have any more questions!

This thread is now set to auto-hide after an hour of inactivity

thin dome