Replacing non-pure virtual functions with CRTP - c++

I'm writing plugins for an application through its C++ SDK. The mechanism is fairly simple. A plugin provides its functionality through predefined interfaces. This is done by having server classes inherit from one implementation class per interface, which contains either pure vitual functions or non-pure functions with default implementations.
This is very practical as SDK clients only have to override those methods that the plugin requires and/or provide an implementation for the (rare) ones with no default.
What has been bugging me is that everything is known at compile time. The virtual function tables and machinery associated with runtime polymorphism are here only for the sake of providing default implementations.
I'm attempting to remove this overhead while keeping the convenience.
As a (very contrived) example, say I have a couple of servers presenting a single interface (named Blah) consisting of only one method with no default implementation.
// SDK header
struct OldImpl_Blah {
virtual ~OldImpl_Blah() =default;
virtual int mult(int) =0;
};
// plugin source
class OldServer3 : public OldImpl_Blah {
public:
int mult(int i) override { return 3 * i; }
};
class OldServer5 : public OldImpl_Blah {
public:
int mult(int i) override { return 5 * i; }
};
For pure virtual functions, straight forward CRTP works just fine.
// SDK header
template <typename T>
struct NewImpl_Blah {
int mult(int i) { return static_cast<T*>(this)->mult(i); }
};
// plugin source
class NewServer3 : public NewImpl_Blah<NewServer3> {
public:
int mult(int i) { return 3 * i; }
};
class NewServer5 : public NewImpl_Blah<NewServer5> {
public:
int mult(int i) { return 5 * i; }
};
The problem is with non-pure virtual functions, i.e. when there is a default implementation for the method.
// SDK header
struct OldImpl_Blah {
virtual ~OldImpl_Blah() =default;
virtual int mult(int i) { return i; } // default
};
// plugin source
class OldServer3 : public OldImpl_Blah {
public:
int mult(int i) override { return 3 * i; }
};
class OldServer5 : public OldImpl_Blah {
public:
int mult(int i) override { return 5 * i; }
};
I tried to combine CRTP with some expression SFINAE trickery and failed.
I guess what I need is some kind of code dispatching where the base class would either provide a default implementation or forward its arguments to the implementation in the derived class, if it exists.
The problem seems to be that the dispatch should rely on information that is not yet available to the compiler in the base class.
A simple solution would be to just remove the virtual and override keywords in the code. But then the compiler wouldn't check that the function signatures match.
Is there some well known pattern for this situation? Is what I'm asking possible at all?
(Please use small words as my expertise with templates is a bit on the light side. Thanks.)

As always, Yet Another Level of Indirection is the solution. In this particular case, it's the well known technique of public non-virtual functions calling private or protected virtual functions. It have its own uses, independent of what is being discussed here, so check it out regardless. Normally it works like this:
struct OldImpl_Blah {
piblic:
virtual ~OldImpl_Blah() = default;
int mult(int i) { return mult_impl(i); }
protected:
virtual int mult_impl(int i) { return i; }
};
// plugin source
class OldServer3 : public OldImpl_Blah {
protected:
int mult_impl(int i) override { return 3 * i; }
};
With CRTP it's exactly the same:
template <class T>
struct OldImpl_Blah {
piblic:
virtual ~OldImpl_Blah() = default;
int mult(int i) { return static_cast<T*>(this)->mult_impl(i); }
protected:
virtual int mult_impl(int i) { return i; }
};
// plugin source
class OldServer3 : public OldImpl_Blah<OldServer3> {
protected:
int mult_impl(int i) override { return 3 * i; }
};
Disclaimer: CRTP is said to eliminate virtual call overhead by nit requiring functions to be virtual. I don't know if CRTP has any performance benefits when functions are kept virtual.

Consider using something like policy design:
struct DefaultMult {
int mult(int i) { return i; }
};
// SDK header
template <typename MultPolicy = DefaultMult>
struct NewImpl_Blah {
int mult(int i) { return multPolicy.mult(i); }
private:
MultPolicy multPolicy;
};
// plugin source
class NewServer3 {
public:
int mult(int i) { return 3 * i; }
};
class NewServer5 {
public:
int mult(int i) { return 5 * i; }
};
void client() {
NewImpl_Blah<NewServer5> myServer;
}
Also note that in theory using final keyword with override enables compilers to dispatch more optimally than vtable approach. I expect modern compilers to optimise if you use final keyword in your first implementation.
Some helpful refs:
mixin design
For more on policy based design you can watch video or read book / article by Andrei Alexandrescu

To be honest I'm not sure I'd use the following code, but I think it does what the OP is asking for.
This is a minimal, working example:
#include<iostream>
#include<utility>
template<class D>
struct B {
template <typename T>
struct hasFoo {
template<typename C>
static std::true_type check(decltype(&C::foo));
template<typename>
static std::false_type check(...);
static const bool value = decltype(check<T>(0))::value;
};
int foo() {
return B::foo<D>(0, this);
}
private:
template<class T>
static auto foo(int, B* p) -> typename std::enable_if<hasFoo<T>::value, int>::type {
std::cout << "D::foo" << std::endl;
return static_cast<T*>(p)->foo();
}
template<class T>
static auto foo(char, B*) -> typename std::enable_if<not hasFoo<T>::value, int>::type {
std::cout << "B::foo" << std::endl;
return 42;
}
};
struct A: B<A> { };
struct C: B<C> {
int foo() {
std::cout << "C::foo" << std::endl;
return 0;
}
};
int main() {
A a;
a.foo();
std::cout << "---" << std::endl;
B<A> *ba = new A;
ba->foo();
std::cout << "---" << std::endl;
C c;
c.foo();
std::cout << "---" << std::endl;
B<C> *bc = new C;
bc->foo();
}
If I did it right, there are no virtual methods, but the right implementation of foo is called, no matter if you are using a base class or a derived one.
Of course, it is designed around the CRTP idiom.
I know, the member detector class is far from being good.
Anyway, it's enough for the purpose of the question, so...

I believe, I understand what you are trying to do. If I am correct in my understanding, that can't be done.
Logically, you would want to have mult in Base to check if mult is present in the child struct - and if it does, call it, if it does not, provide some default implementation. The flaw here is that there always be mult in child class - because it will inherit implementation of checking mult from Base. Unavoidably.
The solution is to name function differently in the child class, and in the base check for presence of differently named function - and call it. This is a simple thing to do, let me know if you'd like the example. But of course, you will loose the beauty of override here.

Related

Can a class have a member that is another with the same name in the same namespace?

Suppose I have two classes with the same name in the same namespace in two different files.
This is so I can construct another object with each of the two classes, following the same interface but with some functions that behave differently.
For the differently behaving functions, I will redefine them in one instance of the class.
For the functions behaving the same way, I want to construct an instance of the other class and forward calls.
Is there a way to do this? Clearly I can't have two classes in the same namespace, but perhaps I can redefine the namespace/classname of the class I want to be a member in order to forward calls?
For example:
//file_1.h
namespace x {
class y {
}
}
//file_2.h
#include "file_1.h"
namespace x {
class y {
// member of same class in the other file
y memberName;
}
}
You can not modify a class after it has been declared and you can not declare two different classes with the same name.
You can declare a class hierarchy with virtual methods and use a pointer to the base. For example:
class A {
public:
virtual void f() = 0;
};
class B : public A {
void f() override {std::cout << "B" << std::endl;}
};
class C : public A {
void f() override {std::cout << "C" << std::endl;}
};
int main()
{
A *a1 = new B;
A *a2 = new C;
a1->f(); // B
a2->f(); // C
return 0;
}
Although both a1, a2 are pointers to A, the code will print:
B
C
If you do not want to made this class hierarchy public, you can use the pimpl technique. It allows you to hide the real implementation of a class.
For example:
// File: A.h
class A {
class AImpl;
std::unique_ptr<AImpl> m_pimpl;
public:
explicit A();
void f();
};
// File A.cpp
class A::AImpl {
public:
void f() { std::cout << "A" << std::endl;};
};
A::A() : m_pimpl(new AImpl) {
}
void A::f() {
m_pimpl->f();
}
Now, you can define inside your cpp file the implementation of class AImpl. You can even use a class hierarchy for AImpl to create different behaving objects depending on the class that you have created internally.
Suppose I have two classes with the same name in the same namespace in two different files.
Then you have violated a rule called thd ODR or one definition rule. Doing so makes your program ill-formed, no diagnostic required.
If you have a class Alice that wants tomuse another class Bob, but you want two different definitions for how Bob works, the solutions are called "polymorphism".
Polymorphism is the ability for two or more classes to substitute for one.
There are three simple forms of polymorphism. There is using a virtual interface and runtime polymorphism. There is using templates and compile time pokymorphism. Then there is type erasures via function pointers.
The easiest is defining a virtual interface.
struct IBob {
virtual int count() const = 0;
virtual ~IBob() {}
};
struct Alice {
std::unique_ptr<IBob> my_bob = nullptr;
void do_stuff() const {
if(my_bob) std::cout << "Count is:" << my_bob->count() <<"\n";
}
};
now we can define two implementations of IBob:
struct Bob0:IBob{
int count() const final { return 7; }
};
struct Bob1:IBob{
std::unique_ptr<IBob> pBob;
int count() const final {
if(pBob) return pBob->count()*2 +1;
else return 1;
}
};
now Bob1 has a IBob, and it uses that IBob to implement its own count.
The template way looks like:
template<class Bob>
struct Alice {
Bob my_bob;
void do_stuff() const {
std::cout << "Count is:" << my_bob.count() <<"\n";
}
};
and the various Bob implementations need no virtual or inheritance. Here you must pick which Bob at compile time at each point of use.
The manual function pointer type erasure solution is more complex. I'd advise against it.
When you include a file is like adding the content to that cpp file.
So that means you will have the same name for different classes.
There is a possibility to use the same name by using typedef.
class A {
public:
static void func() {}
};
class B {
public:
static void func() {}
};
void funcA() {
typedef A C;
C::func();
}
void funcB() {
typedef B C;
C::func();
}
int main()
{
funcA();
funcB();
return 0;
}

Virtual function in class template, that doesn't have the template type as parameter/return value

As far as I know, templated virtual functions aren't allowed/possible due to the undefined size of the vtable.
On the other hand, virtual functions inside a class template which don't use the template type seem to be allowed, right?
What about a virtual function that doesn't use the template type as parameter or return type but works on data of the template type? Would that be valid C++?
I have already done some testing and it seems to work.
My Code looks like this:
(Note: For reasons of readability this is only the basic structure, not the real code).
template<typename T>
class Base {
public:
virtual bool compare(void) {
// Basic implementation
return ((value1 + value2) < value3);
}
protected:
T value1, value2, value3;
}
/**
* Derived from Base<ComplexClass> where
* ComplexClass is a Class providing
* a int Value through .getInt()
**/
class Derived : Base<ComplexClass> {
bool compare(void) {
return ((value1.getInt() + value2.getInt()) < value3.getInt());
}
}
main {
Base<int> *intBase = new Base<int>();
Base<double> *doubleBase = new Base<double>();
Base<ComplexClass> *complexBase = new Derived();
intBase->compare(); // Should call base function
doubleBase->compare(); // Should also call base function
complexBase->compare(); // Should call the compare function of Derived
}
As far as i can tell this works like I excepted. Is this just a lucky coincidence or is this valid/good C++ style?
If it's valid, could someone please explain what's happening inside and why some people say it's forbidden/bad practice to derive from class templates and use virtual functions inside of class templates?
Thank you in advance!
PS: I know something similar could have been done by template specialization but I'd like to know if it's also possible this way.
Q As far as I know, templated virtual functions aren't allowed/possible due to the undefined size of the vtable.
A You can have virtual function in class templates.
Example code that compiles and links:
template <typename T>
struct Base
{
virtual T doSomething(T const& in) = 0;
Base(T const& data) : data_(data) {}
T data_;
};
struct Concrete : public Base<int>
{
Concrete(int d) : Base(d) {}
virtual int doSomething(int const& in)
{
return data_*in;
}
};
int main()
{
Concrete a(20);
int b = a.doSomething(10);
}
Q On the other hand, virtual functions inside a class template which don't use the template type seem to be allowed, right?
A The virtual functions of a class template can use anything -- not restricted to not using the template tye.
My example should make that clear.
Q What about a virtual function that doesn't use the template type as parameter or return type but works on data of the template type? Would that be valid C++?
A Yes, it will.
Again, my example should make that clear.
EDIT: Extended example
template <typename T>
struct Base
{
virtual T fun1(T const& in) = 0;
virtual T fun2(int in) = 0;
virtual int fun3(T const& in) = 0;
virtual int fun4(int in) = 0;
Base(T const& data) : data_(data) {}
T data_;
};
struct Concrete : public Base<int>
{
Concrete(int d) : Base(d) {}
virtual int fun1(int const& in)
{
return data_*in;
}
virtual int fun2(int in)
{
return fun1(in);
}
virtual int fun3(int const& in)
{
return fun1(in);
}
virtual int fun4(int in)
{
return fun1(in);
}
};
int main()
{
Concrete a(20);
int b = a.fun1(10);
int c = a.fun2(10);
int d = a.fun3(10);
int e = a.fun4(10);
}
This is perfectly valid. However, here you can have the same behaviour with specialization or just overloading, e.g.
template<typename T>
struct Base
{
bool compare() const { return val(value1) + val(value2) < val(value3); }
protected:
T value1, value2, value3;
private:
template<typename U>
static U val(U a) { return a; }
static int val(const ComplexClass& a) { return a.getInt(); }
};
Better keep virtual functions for when it's really needed.
And try to gather as much as possible shared code in a single place, minimizing what is to be specialized.

Explicit overriding

msft compilers for C++ support explicit overriding (see http://msdn.microsoft.com/en-us/library/ksek8777.aspx)
// could be declared __interface I1, making the public scope and pure virtual implied
// I use the more expressive form here for clarity
class I1
{
public:
virtual void foo() = 0;
};
class I2
{
public:
virtual void foo() = 0;
};
class C : public I1, public I2
{
public:
virtual void I1::foo() { cout << "I1::foo\n"; }
virtual void I2::foo() { cout << "I2::foo\n"; }
};
int main()
{
C c;
static_cast<I1*>(&c)->foo();
static_cast<I2*>(&c)->foo();
cin.get();
}
But gcc doesn't like this. A simple "explicit overrides" online search yields information about the new keyword override. That isn't necessarily related to what I am looking for. Is this feature supported in some other way in c++11 (per spec) or at least in some way in gcc?
Note: an acceptable answer can be a hack - as long as it is in the same spirit of the question and not a new design to solve a different problem.
I believe the only way is via intermediate classes which implement the functionality:
class Impl1 : public I1 {
public:
void foo() { cout << "I1::foo\n"; }
};
class Impl2 : public I2 {
public:
void foo() { cout << "I2::foo\n"; }
};
class C : public Impl1, public Impl2
{
};
Granted, this makes it rather more complicated once these functions need to access members of C – they can’t, the members need to be passed around in a convoluted manner.
By the way, no need for pointers; you can use references:
int main()
{
C c;
static_cast<I1&>(c).foo();
static_cast<I2&>(c).foo();
}
(Or use explicit qualification which avoids the virtual dispatch altogether:)
c.Impl1::foo();
c.Impl2::foo();

C++ : calling the right method of a derived class according to the types of the arguments

Let say we have a base class and its two derived classes; The base class owns a method execute and each derived class implements a different version of this method with different types and number of arguments; I can't use a virtual method because signature should be then exactly the same for each derived class; My goal is to offer a base execute method which accepts any kind of arguments, deducts their types, and dispatch them to the right method in the right derived class; I took a look at the Visitor pattern, but I'm looking for a more flexible and elegant solution;
edit : I want to store those classes in a vector, so I need a base class
Here is my try (I don't know what to put in the body of base execute) under gcc 4.5:
class Base {
public:
Base();
~Base();
template<typename ...Args>
void execute(Args... arg)
{
//calls the right method
//execute(int i) or execute(int i, float f)
//as Args are int or int and float
}
};
class DerivedA : public Base
{
public:
DerivedA();
~DerivedA();
void execute(int i){ /*do something with i*/}
};
class DerivedB : public Base
{
public:
DerivedB();
~DerivedB();
void execute(int i, float f){/*do something with i and f*/}
};
void test()
{
Base* b1 = new DerivedA();
Base* b2 = new DerivedB();
int i = 5;
b1->execute(i); //should call DerivedA.execute(int i)
float f = 5.0f;
b2->execute(i, f); //should call DerivedB.execute(int i, float f)
}
The following uses an intermediate class in between the base and the derived class:
#include <utility>
#include <iostream>
#include <stdexcept>
template<typename... Args> class Intermediate;
class Base
{
public:
virtual ~Base() {}
template<typename ...Args>
void execute(Args... args)
{
typedef Intermediate<Args...>* pim;
if (pim p = dynamic_cast<pim>(this))
{
p->execute(std::forward<Args>(args)...);
}
else
{
throw std::runtime_error("no suitable derived class");
}
}
};
template<typename... Args> class Intermediate:
public Base
{
public:
virtual void execute(Args ... arg) = 0;
};
class DerivedA:
public Intermediate<int>
{
public:
void execute(int i)
{
std::cout << "DerivedA: i = " << i << "\n";
}
};
class DerivedB:
public Intermediate<int, float>
{
public:
void execute(int i, float f)
{
std::cout << "DerivedB: i = " << i << ", f = " << f << "\n";
}
};
int main()
{
Base* b1 = new DerivedA();
Base* b2 = new DerivedB();
int i = 5;
b1->execute(i); //should call DerivedA.execute(int i)
float f = 5.0f;
b2->execute(i, f); //should call DerivedB.execute(int i, float f)
}
You cannot have an arbitray (= unbounded) number of virtual functions in the base class. You have to decide which functions should be available and declare those. Otherwise you don't need virtual functions, and you could just make some compile-time dispatch, perhaps simply through overload resolution like this:
struct Base
{
void foo(int a) { dynamic_cast<DerA*>(this)->fooimpl(a); }
void foo(int a, float b) { dynamic_cast<DerB*>(this)->fooimpl(a, b); }
void foo(bool a, char b) { dynamic_cast<DerC*>(this)->fooimpl(a, b); }
virtual ~Base() { } // dynamic cast requires polymorphic class
};
You should add a check for validity, of course:
if (DerA * p = dynamic_cast<DerA*>(this)) { p->fooimpl(a)); }
Compile-time or runtime?
You need to know if you can decide at compile-time which method you want to call. If you want to decide at runtime, then that is called multiple dispatch and there is no built-in, short solution for it in C++ (see also the question Multiple dispatch in C++). You can sort of emulate it with the Visitor pattern or double dispatching. Here is a paper about implementing multimethod support for a C++ compiler by Bjarne Stroustroup and others.
Compile time implementation with a free function
If you know the type of your instances at compile time (i.e. you don't have to use Base* pointers), you can use a variadic template approach with static polymorphism (and you won't even need a common base class):
#include <iostream>
class DerivedA //: public Base
{
public:
void execute(int i)
{
std::cout << "I'm DerivedA::execute(int)! " << std::endl;
}
};
class DerivedB //: public Base
{
public:
void execute(int i, float f)
{
std::cout << "I'm DerivedB::execute(int, float)! " << std::endl;
}
};
template<typename Class, typename... Args>
void execInvoker(Class* obj, Args... args)
{
static_cast<Class*>(obj)->execute(std::forward<Args>(args)...);
}
int main(int argc, char* argv[])
{
DerivedA a;
DerivedB b;
int i = 5;
float f = 5.2f;
execInvoker(&a, i);
execInvoker(&b, i, f);
}
You will get compilation errors if you try to invoke an execute method that doesn't exist (wrong types, or wrong number of arguments). I tested the above code with g++ 4.6 and the output is the expected:
$ g++ -std=c++0x -Wall variadic.cpp
$ ./a.out
I'm DerivedA::execute(int)!
I'm DerivedB::execute(int, float)!
A similar approach without a free function
If you don't want to use a free function, you can use a template proxy class to save the type information.
template<typename Class>
class Proxy
{
private:
Class* obj;
public:
Proxy(Class* _obj) : obj(_obj) {}
template<typename... Args>
void execute(Args... args)
{
obj->execute(std::forward<Args>(args)...);
}
};
This allows the following code:
Proxy<DerivedA> proxy(&a);
proxy.execute(i);
An obvious advantage of this approach is that you can pass this proxy object to template functions such as this one:
template<typename Class>
void proxyUser(Proxy<Class>& p)
{
p.execute(4, 0.3f);
}
And it will call the correct execute. For specific cases, you can specialize this template function.
If I understand correctly what you are trying to accomplish, you could find it useful having a look at the "double dispatch" pattern:
double dispatch is a special form of multiple dispatch, and a mechanism that dispatches a function call to different concrete functions depending on the runtime types of two objects involved in the call (source)
Roughly: your client object calls "execute" on the target object:
target.execute(client);
the target object calls a method on an intermediate object that acts as an extended virtual table (actually, a multi-dispatch table):
dispatchTable.execute(client, *this); //-- target calls this
and dispatch table at its turns calls the right method (with the complete signature) on the target object:
<get arguments from client>
target.specific_execute(arguments)
Alternatively, and possibly more conveniently, the dispatch table mechanism can be offered by the client object itself. So, target::execute calls:
client.execute(target);
and client::execute(target) will finally call:
target.specific_execute(args);
The client class will provide a set of overaloaded execute methods, each for a specific target type. The method will encapsulate the knowledge about the specifics of that object execute arguments.
This could require some refactoring of your design (in the first approach, client has to offer a way to retrieve the arguments to the call), and it possibly looks like quite a low-level implementation (a dispatch table), but it is a clean approach, IMO.
class Client;
struct Base {
virtual void dispatch(Client& c);
void execute(Base& b) {
std::cout << "void execute(Base&)" << std::endl;
}
};
struct DerivedA : public Base {
void exec(int i){
/*do something with i*/
std::cout << "void execute(int i)" << std::endl;
}
};
struct DerivedB : public Base {
void exec(int i, float f)
{
std::cout << "void execute(int i, float f)" << std::endl;
}
};
struct Client {
int i;
float f;
void execute(Base& obj) {
}
void execute(DerivedA& obj) {
obj.exec(i);
}
void execute(DerivedB& obj) {
obj.exec(i, f);
}
void doTest() {
Base* b1 = new DerivedA();
Base* b2 = new DerivedB();
b1->dispatch(*this);
b2->dispatch(*this);
}
};
void Base::dispatch(Client& c) {
c.execute(*this);
}
void DerivedA::dispatch(Client& c) {
c.execute(*this);
}
void DerivedB::dispatch(Client& c) {
c.execute(*this);
}
int main (int argc, char * const argv[]) {
// insert code here...
std::cout << "Hello, World!\n";
Client c;
c.doTest();
return 0;
}

Protected External Resource Usage

I'm working with some code where I have the following setup.
struct data
{
void change_safe_member(){}
void read_data(){}
void change_unsafe_member(){}
};
struct data_processor
{
std::shared_ptr<data> get_data(){}
void return_data(std::shared_ptr<data> my_data)
{
my_data->change_unsafe_member(); // ONLY data_processor should call this function.
}
};
struct client
{
void foo(std::shared_ptr<data_processor>& my_processor)
{
auto my_data = my_processor->get_data();
my_data->change_safe_member();
//my_data->change_unsafe_member(); SHOULD NOT BE POSSIBLE TO CALL
my_processor->return_data(my_data);
}
};
The change_unsafe_member should only be used internally by the processor so I would like to hide it or disable it for the client. But I don't know of any nice ways of doing this without resorting to ugly casts...
struct internal_data
{
void change_unsafe_member(){}
};
struct data : public internal_data
{
void change_safe_member(){}
void read_data(){}
};
struct data_processor
{
std::shared_ptr<data> get_data(){}
void return_data(std::shared_ptr<data> my_data)
{
auto internal_data = std::static_pointer_cast<internal_data>(my_data);
internal_data->change_unsafe_member();
}
};
Anyone know of a good pattern to use in situations like this? Maybe visitor pattern or something similar?
EDIT:
As pointed out in the comments one could declare friend classes, there is however one problem... the following will not work.
struct data
{
void change_safe_member(){}
void read_data(){}
private:
friend class data_processor;
virtual void change_unsafe_member(){}
};
struct data_decorator : public data
{
data_decorator(const std::shared_ptr<data>& decoratee) : decoratee_(decoratee){}
void change_safe_member(){decoratee_->change_safe_member();}
void read_data(){decoratee_->read_data();}
private:
virtual void change_unsafe_member()
{
std::cout << "Hello!"; // Add functionality
decoratee_->change_unsafe_member(); // Won't work... compiler error
}
std::shared_ptr<data> decoratee_;
};
// Another example
struct data_group_decorator : public data
{
data_group_decorator (const std::vector<std::shared_ptr<data>>& decoratees) : decoratees_(decoratees){}
void change_safe_member(){decoratee_->change_safe_member();}
void read_data(){decoratee_->read_data();}
private:
virtual void change_unsafe_member()
{
for(size_t n = 0; n < decoratees_.size(); ++n)
decoratees_[n]->change_unsafe_member(); // Won't work... compiler error
}
std::vector<std::shared_ptr<data>> decoratees_;;
};
You can make this happen with inheritance.
struct Y;
struct X {
friend struct Y;
private:
change_unsafe_member() {}
};
struct Y {
protected:
change_unsafe_member(X& x) { x.change_unsafe_member(); }
};
struct some_other : Y {
X x;
change_safe_member() { change_unsafe_member(x); }
};
Any class that inherits from Y can gain X's friendship for any functions that Y defines as effectively forwards from X.
Your last example looks like what you're really asking for is inherited friendship; i.e. you want to have a hierarchy of decorator - derived classes which are all allowed to call the private member function in data. That's answered (with "generally no") elsewhere:
Why does C++ not allow inherited friendship?
Polymorphism might provide some relief in your specific scenario, make class data_decorator an "almost pure" virtual base class, with the only nonvirtual member being a protected change_unsafe_member(), and make that in turn a friend of class data. All decorators would inherit from data_decorator, and call its protected nonvirtual member.