Suppose I have a template class:
template<typename T>
struct Node
{
T val;
Node *next;
};
template<typename T>
class MyClass
{
T data1_;
T data2_;
vector<Node<T> > vi_;
};
Now I want to serialize MyClass to disk using different method. For example, using raw c system call write/read or c++ fstream , or other approach.
I introduce another template parameter to do that:
template<typename T,typename SerializerTrait>
class MyClass
{
T data1_;
T data2_;
vector<Node<T> > vi_;
void save()
{
SerializerTrait::save(data1_);
SerializerTrait::save(data2_);
SerializerTrait::save(vi_);
}
};
//serializer
template <typename>
class RawC
{
static FILE *f;
static void save(T t){fwrite(&t,sizeof(t),1,f);}
...
}
template <typename>
class StreamCPP
{
static fstream *f;
static void save(T t){*f<<t);}
...
}
It can work. But it seems not elegant.
Strategy pattern is a good solution, but template function cannot be virtual.
Is there any better way to do that?
You can do something like this:
template<typename T>
class MyClass
{
template <class SERIALIZER>
void save()
{
SERIALIZER::save(data1_);
SERIALIZER::save(data2_);
SERIALIZER::save(vi_);
}
//or with serializer instance
template <class SERIALIZER>
void save(SERIALIZER & s)
{
s.save(data1_);
s.save(data2_);
s.save(vi_);
}
virtual void save(SerializerDetail * s)
{
s->save(this);
}
};
class SerializerDetail
{
public:
template <class T>
void save(T * p)
{
p->save<SomeSerializer>();//use the first two save functions
//or
p->save(SerializerInstance);//or this of you want it
}
};
Related
In C++ is it possible to define multiple methods based of the number of template parameters provided? Similar to how variadic functions work?
With functions I can do
template <class ...Args>
struct VariadicFunctionCallback {
typedef std::function<void(std::shared_ptr<Args>...)> variadic;
};
But what I want to know is if I could do something similar but to create multiple functions instead of multiple arguments
template <class ...FunctionArg>
class Example {
void Function(FunctionArg)...
}
Which would then allow me to do something like
template <>
class Example<int, float> {
void Function(int i) {
...
}
void Function(float f) {
...
}
}
And if this is possible what are the advantages over my current setup which is like
template<class EventType>
class EventHandler {
public:
void HandleEvent(const std::shared_ptr<EventType>& event) {
}
};
class ExampleEvent : public Event<ExampleEvent> {
};
class ExampleHandler : public EventHandler<ExampleHandler>, EventHandler<Events::ShutdownEvent> {
public:
void HandleEvent(const std::shared_ptr<ExampleEvent> &event);
void HandleEvent(const std::shared_ptr<Events::ShutdownEvent> &event);
};
--Edit--
I ended up with a mix if the two solutions.
It is probably not the best and I will continue to play around with and improve it overtime.
template <class EventType>
class BaseEventHandler {
public:
EventIdentifier GetIdentifier() const {
return EventType::GetIdentifier();
}
virtual void HandleEvent(const std::shared_ptr<EventType> &event) = 0;
};
template<class EventType, class ...EventTypes>
class EventHandler: public BaseEventHandler<EventTypes>... {
};
Which then allows me to do
class EventListener: public EventHandler<ShutdownEvent, MousePosEvent, WindowCloseRequestEvent> {
void HandleEvent(const std::shared_ptr<ShutdownEvent> &event);
void HandleEvent(const std::shared_ptr<MousePosEvent> &event);
void HandleEvent(const std::shared_ptr<WindowCloseRequestEvent> &event);
}
I suppose you can make Example a sort of recursive self-inheritancing class; something as
template <typename ...>
struct Example
{
// dummy Function() to end the recursion
void Function ()
{ }
};
template <typename T0, typename ... Ts>
struct Example<T0, Ts...> : public Example<Ts...>
{
using Example<Ts...>::Function;
void Function (T0 const &)
{ };
};
So you can write
int main ()
{
Example<int, long, float> e0;
e0.Function(0);
e0.Function(0L);
e0.Function(0.0f);
}
-- EDIT --
The OP ask
Could a specialisation then be preformed on top of this?
Do you mean something as follows?
template <typename ...>
struct Example
{
// dummy Function() to end the recursion
void Function ()
{ }
};
template <typename T0, typename ... Ts>
struct Example<T0, Ts...> : public Example<Ts...>
{
using Example<Ts...>::Function;
void Function (T0 const &)
{ };
};
template <typename ... Ts>
struct Example<float, Ts...> : public Example<Ts...>
{
void FunctionFloat (float const &)
{ };
};
int main ()
{
Example<int, long, float> e0;
e0.Function(0);
e0.Function(0L);
e0.FunctionFloat(0.0f);
//e0.Function(0.0f); // compilation error
}
This answer start's with max66's answer, more or less
We start with a class that uses recursive inheritance to implement our function. In my case, I chose operator(), and I used a variadic using declaration to bring all children operator() into scope:
namespace detail{
template<class T, class... U>
struct ExampleImpl : ExampleImpl<U>...{
using ExampleImpl<U>::operator()...;
void operator()(T _arg){/*...*/}
};
}
Where my answer diverges from max66's is in that we'll use this ExampleImpl class to compose our Example class:
template<class... T>
class Example
{
public:
template <class U>
void Function(U arg)
{
impl(arg);
}
void Function(float arg)
{
/*Your specialization code*/
}
private:
detail::ExampleImpl<T...> impl;
};
I do it this way for 2 reasons:
This inheritance is an implementation-detail and something you'd want to hide from clients.
*Now we can easily specialize our Function function for whatever type we want because we always have a choice in whether to call through to our instance of ExampleImpl or not.
Demo
If ExampleImpl needs to use member variables of your Example class, then you can either turn ExampleImpl into a full-fledged PIMPL class, or modify its constructor or operator() to accept additional arguments as a form of Dependency Injection
*You could just as easily perform full class specialization where float is one of the template parameters in the specialization, and define your own Function. Or you could use a form of tag dispatching to hide the float version unless it was in the list of template types.
Tag dispatch demonstration
I have a template class Field<T> which inherits from a non-template abstract base class AbstractField to be able to store all different kinds of Field<T> * types in a std::vector<AbstractField *>. My setup is as follows:
#include <vector>
class AbstractField
{
public:
virtual ~AbstractField() {};
// Something similar to: template<class T> T getValue() const; ?
};
template<class T>
class Field : public AbstractField
{
private:
T d_;
public:
Field(T d) : d_(d) {}
T getValue() const { return d_; }
};
int main()
{
AbstractField *f = new Field<double>(0.1);
// How to call: f->getValue(); ?
return 0;
}
I was wondering what would be the most natural way to call f->getValue() since I can't use a virtual template member function in the AbstractField class. As far as possible, I would prefer not using boost. Any hints are welcome!
EDIT:
Corrected std::vector<Field<T> > to std::vector<AbstractField *>. Sorry for the confusion.
Maybe this:
template <typename> struct Field;
struct AbstractField
{
virtual ~AbstractField() {}
template <typename T> T getValue()
{
return dynamic_cast<Field<T>&>(*this)->get();
}
};
template <typename T> struct Field : AbstractField
{
T & get();
// ...
};
I'm writing a wrapper for some benchmark code and want to execute the same code for every templated class type in an already templated function.
There is the benchmark class:
template<class T>
class Benchmark : public Interface, public T {
virtual void Execute();
}
And as class T I want to use a type that is basically only there for initializing class variables e.g.
template<class S>
struct GenericBench {
GenericBench();
S var1, var2, var3;
};
The question now: is it somehow possible to define a specialized function Execute for every mutation of GenericBench for this kind of class inheritance constelation?
template<>
void Benchmark<GenericBench>::Execute() {
// my benchmark code
}
A main call would then look something like this:
myBench->Execute<GenericBench<int>>();
The following code compiled and linked in g++
struct Interface { };
template<class T>
class Benchmark: public Interface, public T {
public:
virtual ~Benchmark() { }
virtual void Execute();
};
template<class S>
struct GenericBench {
GenericBench() { }
S var1, var2, var3;
};
// Specialization of the class
template<class S>
class Benchmark<GenericBench<S> >: public Interface, public GenericBench<S> {
public:
virtual ~Benchmark() { }
virtual void Execute() {
// do things
}
};
int main(int argc, char **argv) {
Benchmark<GenericBench<int> > myBench;
myBench.Execute();
}
Since you said that you want to define specialized responses on basis of type you are working on... making function template and then specializing it will help.
Following is an examples
(Apologies for not using example u provided.. I just want to show the approach. Let me know if it works for you)
template <class S> class myData {
public:
};
namespace mySpecializedFunction {
template<class P> void someFunction(P check) {std::cout<<"3333\n";return;}
template<> void someFunction(myData<int> check) {std::cout<<"4444\n";return;}
template<> void someFunction(myData<float> check) {std::cout<<"5555\n";return;}
}
template <class T> class myClass: public T {
public:
template <class Q> void someFunction( Q check) { mySpecializedFunction::someFunction(check); return ; }
};
And Using it like this...
myData<int> d1;
myData<float> d2;
myClass< myData<int> > c1;
c1.someFunction(d1);
myClass< myData<float> > c2;
c2.someFunction(d2);
I'm trying to create a class which will contain a map of type_index keys mapped to pointers of each type passed as a template argument. This would allow me to specify a series of types my class will rely on in it's declaration.
I've done a bit of research but can only seem to find ways to unpack arguments, rather than types. I'm new to this subject, and would appreciate any clarification on terminology, or references to relevant text.
template <typename T>
T* SomeFakeFactoryGetter() { return new T(); }
template <class... Injected>
class UtilityProvider
{
public:
template <class U>
U* GetUtility()
{
std::type_index idx = std::type_index(typeid(U));
assert(_injectedClasses.find(idx) != _injectedClasses.end());
return reinterpret_cast<U*>(_injectedClasses[idx]);
}
// **
// How would I *unpack* all types for use as indices into my map?
// ( I realise this function is not what I want.)
template <Injected... C>
void Unpack()
{
_injectedClasses[std::type_index(typeid(C))] = SomeFakeFactoryGetter<C>();
}
private:
typedef std::unordered_map<std::type_index, void*> InjectedMap;
InjectedMap _injectedClasses;
};
class Bar{ public: void A() { printf("Hello bar"); } };
class Baz{ public: void B() { printf("Hello baz"); } };
class Nope {};
class Foo : public UtilityProvider<Bar, Baz>
{
public:
Foo()
{
GetUtility<Bar>()->A();
GetUtility<Nope>(); // Fail. User must specify which utilities this class will use.
}
};
What I've done in this situation is to create a dummy function to expand these expressions into, but it looks quite hideous:
template <int ... Dummies>
void dummy(int&& ...){}
template <class ... C>
void Unpack()
{
dummy(((_injectedClasses[std::type_index(typeid(C))] =
SomeFakeFactoryGetter<C>()), 0)...);
}
Note that in your case I think you'll be better off with using insert with an initializer_list:
template <class ... C>
void Unpack()
{
_injectedClasses.insert({std::make_pair(std::type_index(typeid(C)),
SomeFakeFactoryGetter<C>())...});
}
I couldn't find a direct mention of this but I believe there is an important difference between the two methods, in case you didn't already know. insert will not override existing key-value pairs, whereas operator[] will. This can affect which method you should use if if this is important to you.
An alternative approach:
template <typename ... C> struct Unpacker;
template <typename Tail, typename ... Queue>
struct Unpacker<Tail, Queue...>
{
void operator () (InjectedMap& injectedClasses) const
{
_injectedClasses[std::type_index(typeid(Tail))] = SomeFakeFactoryGetter<Tail>();
Unpacker<Queue...>()(injectedClasses);
}
};
template <>
struct Unpacker<>
{
void operator () (InjectedMap& injectedClasses) const {}
};
Given class Foo
template <typename T>
class Foo
{
public:
...other methods..
void bar()
{
...
m_impl.doSomething();
...
}
void fun()
{
...
m_impl.doSomethingElse();
...
}
void fubar()
{
...
}
private:
T m_impl;
};
I wanted to cater for situations where T is a boost::shared_ptr.
In this case the only change to class Foo is that it should invoke
m_impl->doSomething();
instead of
m_impl.doSomething();
I ended up defining FooPtr in the same header
template <typename T>
class FooPtr
{
public:
...other methods..
void bar()
{
...
m_pImpl->doSomething();
...
}
void fun()
{
...
m_pImpl->doSomethingElse();
...
}
void fubar()
{
...
}
private:
boost::shared_ptr<T> m_pImpl;
};
Now while the approach works for all classes that I want to use with Foo,
the problem is that I have a lot of duplicate code lying around and any changes
I make to Foo, I also have to make to FooPtr.
How can I refactor the code? E.g. Is there any way that I can determine at compile time if T is of type boost::shared_ptr, and then specialise just the bar and fun methods to invoke the -> operator?
Edit:
Thanks for all the answers so far! I just need some time to work through them all and see which solution is the best fit for our software.
Edit 2:
#Matthieu: This is the test code I was using
class FooImpl
{
public:
void doIt()
{
cout << "A" << std::endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Foo<FooImpl> foo;
foo.doSomething();
return 0;
}
Sylvain wrote a DRY solution, but I don't like abusing inheritance.
Using a wrapper class to uniformize the interface is easy, especially since pointer semantics work so well!
namespace details {
template <typename T>
struct FooDeducer {
typedef boost::optional<T> type;
};
template <typename T>
struct FooDeducer< T* > {
typedef T* type;
};
template <typename T>
struct FooDeducer< boost::shared_ptr<T> > {
typedef boost::shared_ptr<T> type;
};
} // namespace details
template <typename T>
class Foo {
public:
// methods
void doSomething() { impl->doIt(); }
private:
typedef typename details::FooDeducer<T>::type Type;
Type impl;
};
Here, relying on boost::optional which provides the OptionalPointee semantics, we nearly get the same behavior than pointers.
One point I'd like to emphasize though, is the difference in the copying behavior. boost::optional provides deep copy.
class A
{
public:
void doSomething() {}
};
template <typename T>
class Foo
{
public:
void bar()
{
Impl(m_impl).doSomething();
}
private:
template<typename P>
P& Impl(P* e)
{
return *e;
}
template<typename P>
P& Impl(std::shared_ptr<P> e)
{
return *e;
}
template<typename P>
P& Impl(P& e)
{
return e;
}
T m_impl;
};
You can write a caller class template, whose job is to call the function, either using syntax obj.f() or obj->f(), based on the type of obj.
Here is a small example that demonstrates this approach:
template<typename T>
struct caller
{
static void call(T &obj) { obj.f(); } //uses obj.f() syntax
};
template<typename T>
struct caller<T*>
{
static void call(T* obj) { obj->f(); } //uses obj->f() syntax
};
And this caller class template is used by this sample class:
template<typename T>
struct X
{
T obj;
X(T o) : obj(o) {}
void h()
{
caller<T>::call(obj); //this selects the appropriate syntax!
}
};
See this online running demo at ideone : http://www.ideone.com/H18n7
--
EDIT:
This is even more generic. Here you can even pass the function which you want to call in caller. Now caller is not hard-coded with the function to be called!
http://www.ideone.com/83H52
I really question whether you should be using a template here at all. Your template parameter has a very clear interface and therefore looks like you should just use an abstract base class.
Do you really need to have an instance? If you do need to change the way the object is represented, this should be done as a separate exercise and not part of the template that uses it.
You can introduce another intermediate template class, something like that:
template < typename T >
class FooBase
{
private:
T m_impl;
protected:
T& impl() { return m_impl; }
};
template < typename T >
class FooBase< boost::shared_ptr< T > >
{
private:
boost::shared_ptr< T > m_impl;
protected:
T& impl() { return *(m_impl.operator ->()); }
};
template < typename T >
class Foo : protected FooBase< T >
{
public:
void bar()
{
impl().DoSomething();
}
};
Now, you only have to code the Foo class only once. And you can specialize it for other smart pointers type by doing partial specialization on FooBase.
Edit: You can also use composition instead of having an inheritance relationship between Foo and FooBase (in which case, I'd probably rename it to FooHelper or something like that).
template < typename T >
class FooHelper
{
private:
T m_impl;
public:
T& impl() { return m_impl; }
};
template < typename T >
class FooHelper< boost::shared_ptr< T > >
{
private:
boost::shared_ptr< T > m_impl;
public:
T& impl() { return *(m_impl.operator ->()); }
};
template < typename T >
class Foo
{
private:
FooHelper< T > m_helper;
public:
void bar()
{
m_helper.impl().DoSomething();
}
};
You can use partial specialization.
template <typename T>
class Foo
{
public:
//...
};
template<typename T> class Foo<boost::shared_ptr<T>> {
//... implement specialization here
};