Forward function calls to underlying data in a wrapper template - c++

I'm writing a template wrapper, something like this
template<class T>
class Wrapper{
public:
Wrapper(T data);
~Wrapper();
void doSomeWrapperWork();
private:
T data;
};
If I want to access the wrapped data, I can obviously add a getter function that returns a reference to the data. I was wondering however if there is anyway, with some template magic, to call directly on the wrapper functions of the underlying wrapped data. In other words, if I have a class TestObject with a public function void foo(), I would like to be able to call it in this way:
Wrapper<TestObject> myWrapper;
myWrapper.foo();
instead of:
myWrapper.getData().foo();
without knowing a priori that such a function exists. Is this possible?

Not quite, until C++ gets reflection we can't easily write wrapper classes without a lot of boilerplate macros
but
You can add an implicit conversion of your wrapper class to T:
template<class T>
class Wrapper{
public:
Wrapper(T data_) : data(data_) {}
operator const T&() const
{
return data;
}
private:
T data;
};
And now your class is convertible to T, so we can call a method on T, with a little work:
usage:
struct Foo
{
constexpr int bar() const
{
return 42;
}
};
int main()
{
constexpr Foo f;
Wrapper<Foo> my_wrapper(f);
static_assert(static_cast<const Foo&>(my_wrapper).bar() == 42);
}
Demo
If you want to avoid the casting yourself, you can write a free function that will call your function, so that implicit conversion may take over:
int call_bar(const Foo& f)
{
return f.bar();
}
Usage:
Foo f;
Wrapper<Foo> my_wrapper(f);
std::cout << call_bar(my_wrapper); // 42
Demo2
I kind of like this approach as all it requires is that we add a free function for each wrapped function we want instead of having to manually do a bunch of casting.

Yes, try something like
#include <iostream>
struct TestObject{
void foo() { std::cout << "TestObject" << std::endl;}
};
template <class T>
struct Wrapper : public T{
Wrapper() {}
void doSomeWrapperWork() {}
};
int main() {
Wrapper<TestObject> wrapper;
wrapper.foo();
}
This allows you to add more functionality as need while still allowing the wrapper to be used as a class T.
This is inspired by the decorator design pattern.

Related

CRTP and lifetime extension

My question is how to make lifetime extension work with CRTP. For example, the following code is perfectly valid:
struct A {
const int& ref;
};
struct B {
const A& a;
};
int main() {
B b{{123}};
return b.a.ref;
}
Its CRTPed version is not:
template <class DerivedT>
class Gettable {
public:
int Get() const {
return static_cast<const DerivedT*>(this)->GetImpl();
}
};
class A : public Gettable<A> {
friend class Gettable<A>;
public:
A(int r) : ref{r}{}
private:
int GetImpl() const {
return ref;
}
const int& ref;
};
template <class T>
class B {
public:
B(const Gettable<T>& gettable) : get_{gettable}{}
int DifferentGet() const {
return get_.Get();
}
private:
const Gettable<T>& get_;
};
int main() {
B b{A{123}};
return b.DifferentGet();
}
The problem is that the original A and its Gettable<A> subobject only exist till the the of B constructor.
I have two questions:
1) Why? It is in no way different from the first case of structs, every lifetime is known at compile time, so I believe that compiler should be able to extend lifetime of all temporaries.
2) Is there any good way to overcome this issue?
1) Why?
Because there is a function involved - the constructor. The temporary is not bound directly to the member, but rather it is bound directly to the argument of the function - whose lifetime extends until the end of the function, which does not extend beyond the full expression that invoces the function.
It is in no way different from the first case of structs
It is different. There is no constructor involved in aggregate initialisation. In that case, the compiler knows the lifetime of the member, and it knows that the member is initialised with the temporary. The lifetime extension rule applies.
so I believe that compiler should be able to extend lifetime of all temporaries.
Consider following example:
struct foo {};
struct bar {
bar(const foo& farg);
const foo& fmem;
};
bar b({});
Should the lifetime of the temporary to extend for the lifetime of b? The standard says, that it doesn't. You appear to be arguing that it should.
Consider following possible implementations of the constructor:
bar::bar(const foo& farg) : fmem{farg} {} // 1
foo fanother;
bar::bar(const foo& farg) : fmem{fanother} {} // 2
If the implementation happens to be 1, then you guessed right, the life time extension is needed. If implementation is 2, then we are unnecessarily extending a temporary that is not referred to anymore.
The language designers chose to not extend such temporary, probably so that life times of temporaries don't get extended unnecessarily. As a consequence, implementation 1 is wrong, as well as your CRTP example.
Concisely: The compiler can only extend the lifetime of a temporary until the lifetime of the reference to which the temporary is bound directly. The compiler cannot know what will be done with the reference within the function. It cannot know that an argument has something to do with a member. Those are only known when the constructor is compiled - not when a call to the constructor is compiled.
2) Is there any good way to overcome this issue?
Use either int* or std::reference_wrapper<int> as the constructor argument. Former is more concise, but latter has convenient property of not having a null representation. These should make it harder to accidentally bind a dangling reference. Regardless, document carefully that the referred object must still be valid when Get is called.
I believe that the most general solution is something like this. This way it works even for multilevel inheritance.
#include <iostream>
#include <utility>
#include <type_traits>
struct NullType {};
// Helper class for casting
template <class Derived>
class DerivedCaster {
protected:
Derived* GetDerived() {
return static_cast<Derived*>(this);
}
const Derived* GetDerived() const {
return static_cast<const Derived*>(this);
}
};
// Matches the predicate against the types and remembers the first
// satisfying argument
template <template <class T> class Predicate, class... Args>
struct FindFirstMatching {
using Type = ... ; // default NullType
static const bool has_match = ... ;
};
// Structure which gets the deepest class from CRTP inheritance chain
// by looking at the instantiated parent class template
template<typename T>
struct GetDeepest
{
using Type = T;
};
template<template<class...> class DT, class... T>
struct GetDeepest<DT<T...>>
{
template <class CLS>
struct Predicate {
static const bool value = std::is_base_of<DT<T...>, CLS>::value;
};
static const bool HasCRTPDerived = FindFirstMatching<Predicate, T...>::has_match;
using DerivedT = typename FindFirstMatching<Predicate, T...>::Type;
using Type = std::conditional_t<HasCRTPDerived, typename GetDeepest<DerivedT>::Type, DT<T...>>;
};
// First abstract class
template <class DerivedT>
class Gettable : public DerivedCaster<DerivedT> {
public:
int Get() const {
return DerivedCaster<DerivedT>::GetDerived()->GetImpl();
}
};
// Second abstract class
template <class DerivedT>
class Incrementable : public DerivedCaster<DerivedT>,
public Gettable<Incrementable<DerivedT>> {
friend class Gettable<Incrementable<DerivedT>>;
public:
int Increment() const {
return ++(this->Get());
}
private:
int GetImpl() const {
return DerivedCaster<DerivedT>::GetDerived()->GetImpl() + 100;
}
};
// non-abstract class
class A : public Incrementable<A> {
friend class Incrementable<A>;
public:
A(int r) : ref_{r}{}
private:
int GetImpl() const {
return ref_;
}
int ref_;
};
// Helper to get the copy of the underlying non-abstract class
template <class T>
auto GetDeepestLevelCopy(const T& arg) {
return static_cast<const typename GetDeepest<T>::Type&>(arg);
}
// Some other class which wants a copy
template <class T>
class B {
public:
B(const Gettable<T>& gettable) : get_{GetDeepestLevelCopy(gettable)}{}
int DifferentGet() const {
return get_.Get();
}
private:
typename GetDeepest<Gettable<T>>::Type get_;
};
int main() {
static_assert(std::is_same_v<GetDeepest<Gettable<Incrementable<A>>>::Type, A>);
static_assert(std::is_same_v<decltype(GetDeepestLevelCopy(std::declval<Gettable<Incrementable<A>>>())), A>);
B b{A{123}};
std::cout << b.DifferentGet() << "\n";
// prints 223
return 0;
}
This looks monstrous, but I don't know whether there is a better solution.

Declare new function inside a class using a template

I'm still learning about templates. I'm not sure whether you can declare/(automatically define) a function inside a class (method) using a template. That is, I have a function template defined like this, for example:
template<typename T>
T getT() {
T result;
return result;
}
And a class, where I want the "new function" to be created, based on the template, like this:
class World{
public:
World();
~World();
getT<int>; //"Magically" create new function from the template (return type 'int')
}
What I actually want is to have only a method with the specific given type in World. That means when I want to "magically" create a method based on the template, I want to sort of copy-paste the template function into the class but with the given type.
For example:
class World{
public:
World();
~World();
//The magically created function with T equal to int
int getT(){
int result;
return result;
}
}
Then of course I expect to be able to call the function:
int main(){
World world; //Create world object
world.getT<int>; //Call the function
return 0;
}
Even though here I say I would call it with getT<int>, it could be only getT() (if it is a perfect copy-paste of the template function).
Be carfull
template<typename T>
T& getT() {
T result;
return result;
}
Will return a reference to a temporary. Please do
template<typename T>
T getT() {
T result;
return result;
}
without "&"
And if it's just for get a specific member, you can use std::tuple.
https://en.cppreference.com/w/cpp/utility/tuple/get
getT<int>; //"Magically" create new function from the template (return type 'int')
I don't think that will work.
It appears as though you would like to be able to use templates like macro expansion. Unfortunately, they are very different things and templates don't work like macro expansion.
However, you can use something like the following:
template<typename T>
struct GetHelper
{
T get()
{
return T{};
}
};
class World : private GetHelper<int>,
private GetHelper<double>
{
public:
World() {}
~World() {}
template <typename T>
get()
{
return static_cast<GetHelper<T>*>(this)->get();
}
};
Now you can use:
World w;
int a = w.get<int>();
double b = w.get<double>();
You may also hide GetHelper as a private type of World as:
class World
{
private:
template<typename T>
struct GetHelper
{
T get()
{
return T{};
}
};
struct Data : GetHelper<int>,
GetHelper<double>{};
Data data;
public:
World() {}
~World() {}
template <typename T>
get()
{
return static_cast<GetHelper<T>*>(&data)->get();
}
};

GoF decorator pattern using static polymorphism (templates) in c++

The decorator pattern is a well known and used pattern for extending functionality of an object without affecting the functionality of other objects of the same class.
How can I use this pattern with as less inheritance involved (using templates)?
Basically, the abstract interface from the polymorphic decorator becomes an implicitly defined concept and you nest the types. For example:
struct BasicCoffee
{
void print() {std::cout << "Coffee!\n";}
};
template <class T>
struct CreamDecorator
{
CreamDecorator(T x) : mNested(x) {}
void print() {mNested.print(); std::cout << "..with cream!\n";}
T mNested;
};
template <class T>
struct SugarDecorator
{
SugarDecorator(T x) : mNested(x) {}
void print() {mNested.print(); std::cout << "..with sugar!\n";}
T mNested;
};
You probably want to use the object generator idiom to make composition easier:
template <class T>
CreamDecorator<T> addCream(T x) {return CreamDecorator<T>(x);}
template <class T>
SugarDecorator<T> addSugar(T x) {return SugarDecorator<T>(x);}
Since you don't have a common type to store decorated objects, you need to use some kind of type inference. For example:
auto myCoffee = addSugar(addCream(BasicCoffee()));
myCoffee.print();
Alternatively, use the value you get from the object generators as an rvalue (This can be useful if you are stuck with C++03 - type erasure can also help!):
addSugar(addCream(BasicCoffee())).print();
You can't do this without explicitly wrapping all public methods of the thing you're decorating. Consider an example:
#include <iostream>
using namespace std;
class Test {
public:
void foo() { cout << "Foo" << endl; }
void bar() { cout << "Bar" << endl; }
};
template <typename T>
class FooDecorator {
public:
explicit FooDecorator(T &t) : t(t) {}
void foo() {
cout << "Baz ";
t.foo();
}
void bar() { t.bar(); }
private:
T &t;
};
template <typename T>
class BarDecorator {
public:
explicit BarDecorator(T &t) : t(t) {}
void foo() { t.foo(); }
void bar() {
cout << "Baez ";
t.bar();
}
private:
T &t;
};
int main() {
Test test;
BarDecorator<FooDecorator<Test> > bd(FooDecorator<Test>(test));
bd.foo();
bd.bar();
}
If you remove the (useless) decoration of bar in the decorator, compilation will fail. This complication aside, it's totally doable... except that all functions accepting the decoreable entity will now also have to be templated. So in the end I don't recommend going down this road.
Another disadvantage of this approach is that even if you only decorate references, code will have to be generated for all template specializations that you end up using, because without the vtable the compiler will have no way of treating methods of different classes with the same name uniformly; and if you make your classes inherit from a single parent which declares these methods as virtual, there is little benefit in using templates anymore - you can potentially gain performance, but you can just as well lose it because more code will bloat the cache.

Template function having its caller's context?

Consider the following code snippet.
template <T>
MyPtr<T> CreateObject()
{
// Do something here first...
// return our new object
return MyPtr<T>(new T());
}
class Foo
{
private:
Foo() { }
public:
static MyPtr<Foo> GetNewInstance()
{
// ERROR: Foo is private...
return CreateObject<Foo>();
}
};
class Bar
{
public:
Bar() { }
};
int main()
{
MyPtr<Bar> bar = CreateObject<Bar>();
return 0;
}
Without resorting to macro for CreateObject (I like the syntax of MyPtr<type> obj = CreateObject<type>(params)), is there a way to make the function CreateObject share the same context as the caller function, thus able to access private Foo c'tor? 'friend' is not what I'm looking for as it would mean anyone calling CreateObject would have access to private Foo c'tor, which is not what I want. Overloading the new operator wouldn't work either as it is imperative that a MyPtr is returned instead of just T* (by assigning T* to MyPtr assigns a type to the object that is required somewhere else).
I guess what I'm looking for is something in between a macro and a template function (syntax of a template function but gets expanded fully like a macro). It would be quite useful to have this feature in this particular case.
Well, you could do that with the passkey pattern:
template<class T, class PassKey>
MyPtr<T> CreateObject(PassKey const& key)
{
return new T(key);
}
class FooKey{
private:
FooKey(){} // private ctor
FooKey(const FooKey&); // undefined private copy ctor
friend class Foo;
};
class Foo{
public:
// public ctor
Foo(FooKey const&){}
static MyPtr<Foo> GetNewInstance()
{
return CreateObject<Foo>(FooKey());
}
};
Example at Ideone.
With C++0x, this can be done much easier than creating a new Key struct every time, since template parameters are now allowed to be friends:
template<class T>
struct PassKey{
private:
PassKey(){}
PassKey(const PassKey<T>&);
friend T;
};
This is basically the same as attempting to use make_shared with a private constructor.
The only way to allow this is with friend. You're pretty much stuck in this case I'm afraid.
I am not sure as to what you are trying to achieve. The simplification to post the problem here has taken away the actual need for the whole thing. So I will just assume that you know what you are doing, and that you really need this (and I suggest that you rethink whether you do need it, as I don't see a point...)
At any rate, you can solve the problem by passing a creator callback to the CreateObject template:
template <typename T, typename Creator>
MyPtr<T> CreateObject( Creator creator )
{
// Do something here first...
return MyPtr<T>(creator());
}
class Foo
{
private:
Foo() {}
static Foo* create() { return new Foo(); }
public:
static MyPtr<Foo> GetNewInstance() {
return CreateObject<Foo>( &Foo:create );
}
// ...
};
The actual issue though, is what does Do something here first actually does that forces you into this complex creation patterns. The fact that it has to be executed before the creation of the new object seems to indicate that there are hidden dependencies not shown in the code, and that usually end up in maintenance nightmares, where someone down the line reorders some code, or adds a new constructor and everything seems to fall apart. Revisit your design and consider whether those dependencies can be simplified or made explicit.
Since you are newing up the object in the very end it really doesn't relate to your CreateObject function. So Change the function prototype to:
template <typename T>
MyPtr<T> CreateObject(T* const p)
{
//...
return MyPtr<T>(p);
}
Usage:
static MyPtr<Foo> GetNewInstance()
{
return CreateObject(new Foo());
}
is there a way to make the function CreateObject share the same context as the caller function
Yes, pass the context you need as an argument (either as an argument to the template, or as an argument to the function).
In practice, move the new T call to a separate function (or struct template, as I chose to do here), like this:
// Dummy representation of your pointer type
template <typename T>
struct MyPtr
{
MyPtr( T *p ) { }
};
// Default constructor template; may be specialized to not use "new" or so.
template <typename T>
struct Constructor
{
static T *invoke() { return new T; }
};
// Needs to be a struct (or class) so 'C' can have a default value
template <typename T, typename C = Constructor<T> >
struct CreateObject
{
MyPtr<T> operator()() {
return MyPtr<T>( C::invoke() );
}
};
class Foo
{
private:
friend struct Constructor<Foo>;
Foo() { }
public:
static MyPtr<Foo> GetNewInstance()
{
return CreateObject<Foo>()();
}
};
If you want to handle different constructor signatures (read: if not all types T have the same constructor signature), you could also choose to not pass the Constructor as a template to the CreateObject struct, but instead use a function argument. That way, you could 'load' a Constructor like this:
// ...
static MyPtr<Foo> GetNewInstance()
{
Constructor<Foo> c( arg1, arg2, arg3 );
return CreateObject<Foo>( c );
}

Creating an interface for an abstract class template in C++

I have the code as below. I have a abstract template class Foo and two subclasses (Foo1 and Foo2) which derive from instantiations of the template. I wish to use pointers in my program that can point to either objects of type Foo1 or Foo2, hence I created an interface IFoo.
My problem is I'm not sure how to include functionB in the interface, since it is dependant on the template instantiation. Is it even possible to make functionB accessible via the interface, or am I attempting the impossible?
Thank you very much for your help.
class IFoo {
public:
virtual functionA()=0;
};
template<class T>
class Foo : public IFoo{
public:
functionA(){ do something; };
functionB(T arg){ do something; };
};
class Foo1 : public Foo<int>{
...
};
class Foo2 : public Foo<double>{
...
};
You are actually attempting the impossible.
The very heart of the matter is simple: virtual and template do not mix well.
template is about compile-time code generation. You can think of it as some kind of type-aware macros + a few sprinkled tricks for meta programming.
virtual is about runtime decision, and this require some work.
virtual is usually implemented using a virtual tables (think of a table which lists the methods). The number of methods need be known at compile time and is defined in the base class.
However, with your requirement, we would need a virtual table of infinite size, containing methods for types we haven't seen yet and that will only be defined in the years to come... it's unfortunately impossible.
And if it were possible ?
Well, it just would not make sense. What happens when I call Foo2 with an int ? It's not meant for it! Therefore it breaks the principle that Foo2 implements all the methods from IFoo.
So, it would be better if you stated the real problem, this way we could help you at a design level rather than at a technical level :)
Easiest way is to make your interface templated.
template <class T>
class IFoo {
public:
virtual void functionA()=0;
virtual void functionB(T arg){ do something; };
};
template<class T>
class Foo : public IFoo<T>{
public:
void functionA(){ do something; };
void functionB(T arg){ do something; };
};
Since functionB's argument type must be known in advance, you have only one choice: Make it a type which can hold every possible argument. This is sometimes called a "top type" and the boost libraries have the any type which gets quite close to what a top type would do. Here is what could work:
#include <boost/any.hpp>
#include <iostream>
using namespace boost;
class IFoo {
public:
virtual void functionA()=0;
virtual void functionB(any arg)=0; //<-can hold almost everything
};
template<class T>
class Foo : public IFoo{
public:
void functionA(){ };
void real_functionB(T arg)
{
std::cout << arg << std::endl;
};
// call the real functionB with the actual value in arg
// if there is no T in arg, an exception is thrown!
virtual void functionB(any arg)
{
real_functionB(any_cast<T>(arg));
}
};
int main()
{
Foo<int> f_int;
IFoo &if_int=f_int;
if_int.functionB(10);
Foo<double> f_double;
IFoo &if_double=f_double;
if_int.functionB(10.0);
}
Unfortunately, any_cast does not know about the usual conversions. For example any_cast<double>(any(123)) throws an exception, because it does not even try to convert the integer 123 to a double. If does not care about conversions, because it is impossible to replicate all of them anyway. So there are a couple of limitations, but it is possible to find workarounds if necessary.
I don't think you can get what you want. Think of this if you were to implement your suggestion: if you have a pointer to an IFoo instance and you call functionB(), what type parameter should you give it? The underlying problem is that Foo1::functionB and Foo2::functionB have different signatures and do different things.
You can achieve something comparable by wrapping the IFoo* pointer in a class and exposing the functionality via generic template functions of the non-templated wrapper class:
#include <assert.h>
// interface class
class IFoo {
public:
virtual int type() const = 0; // return an identifier for the template parameter
virtual bool functionA() = 0;
};
// This function returns a unique identifier for each supported T
template <typename T> static int TypeT() { static_assert("not specialized yet"); }
template <> static int TypeT<bool>() { return 0; }
template <> static int TypeT<double>() { return 1; }
//template <> static int TypeT<...>() { ... }
// templated class
template <typename T> class FooT : public IFoo {
public:
int type() const override { return TypeT<T>(); }
bool functionA() override { return true; }
// not in interface
bool functionB(T arg) { return arg == T(); }
};
// function to create an instance of FooT (could also be static function in FooT)
static IFoo* CreateFooT(int type)
{
switch (type)
{
case 0: return new FooT<bool>();
case 1: return new FooT<double>();
//case ...: return new FooT<...>();
default: return nullptr;
}
}
// Non-templated wrapper class
class FooWrapper {
private:
IFoo *pFoo;
public:
FooWrapper(int type) : pFoo(CreateFooT(type)) { assert(pFoo != nullptr); }
~FooWrapper() { delete pFoo; }
bool functionA() { return pFoo->functionA(); }
template <typename T> bool functionB(T arg)
{
if(pFoo->type() != TypeT<T>())
{
assert(pFoo->type() == TypeT<T>());
return false;
}
return static_cast<typename FooT<T>*>(pFoo)->functionB(arg);
}
// fun stuff:
// (const pendants omitted for readability)
bool changeType(int type)
{
delete pFoo;
pFoo = CreateFooT(type);
return pFoo != nullptr;
}
IFoo* Interface() { return pFoo; }
IFoo* operator->() { return pFoo; }
operator IFoo&() { return *pFoo; }
template <typename T> FooT<T> *InterfaceT()
{
if(pFoo->type() != TypeT<T>())
{
assert(pFoo->type() == TypeT<T>());
return nullptr;
}
return static_cast<typename FooT<T>*>(pFoo);
}
};
int main(int argc, char *argv[])
{
FooWrapper w1(TypeT<bool>());
FooWrapper w2(TypeT<double>());
w1.functionA(); // ok
w2.functionA(); // ok
w1.functionB(true); // ok
w1.functionB(0.5); // runtime error!
w2.functionB(true); // runtime error!
w2.functionB(0.5); // ok
// fun stuff
w2.changeType(TypeT<bool>()); // older changes will be lost
w2.functionB(true); // -> now ok
w1.Interface()->functionA();
w1->functionA();
IFoo &iref = w1;
iref.functionA();
FooT<bool> *ref = w1.InterfaceT<bool>();
ref->functionB(true);
return 0;
}
It is of course your responsibility to call the functions with the correct types, but you can easily add some error handling.