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);
Related
Is there a way to automatically create one method per variadic template argument?
For example, in the code below, I want to be forced to override void x(a &v) and void x(b &v) in class i:
#include <type_traits>
#include <stdlib.h>
#include <stdio.h>
class a {
};
class b {
};
template <typename ...T>
class t {
public:
virtual void x(T &v) = 0;
};
class i : public t<a, b>
{
};
int
main (int argc, char *argv[])
{
i ii;
return 0;
}
You can make a t_impl that holds the virtual function for a single T like
template <typename T>
class t_impl
{
public:
virtual void x(T &v) = 0;
};
and then t would inherit from it like
template <typename ...T>
class t : t_impl<T>... // can use public, protected or private inheritance
{
public:
using t_impl<T>::x...; // used to import t_impl<T>::x into the public space
// any additional common members
};
Instead of making t a variadic template, just template it on a single type:
template <typename T>
class t {
public:
virtual void x(T &v) = 0;
};
and inherit base classes like this instead:
class i : public t<a>, t<b>
{
virtual void x(a &v) {}
virtual void x(b &v) {}
};
Here's a demo.
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 really ugly implementation of something that I want to refactor but I am not sure how. Here is what I have:
Some templated object
template< typename T>
class Thing { };
An interface
class IService {
public:
virtual void func(void* arg) = 0;
};
A templated class implementing it
template< typename T>
class Service< T> : public IService {
virtual void func(void* arg) {
func((Thing< T>* )arg);
}
void func(Thing< T>* arg) {
// do something with arg
}
};
The reason is that I want a non-templated IService that I can pass around. templating IService will cause massive refactor through a large code base.
So instead, I instantiate Service< T> objects, pass around the IService, and call func with templated Thing objects, which does an ugly cast to a similar function that takes the actual Thing object. Is there any clean way to achieve this without templating IService?
Edit: some more context. This is what I really want:
template<typename T>
class IService {
public:
virtual void func(Thing<T>* arg) = 0;
};
However, I cannot template IService.
Assuming that you don't want to or can't give Thing a base class, and given that a given Service<T> can only handle Things which have the same T, you could do this:
class IService {
public:
template <typename T>
void func(Thing<T>* arg) {
auto self = dynamic_cast<Service<T>*>(this);
if (self) {
self->func(arg);
} else {
// decide how to handle this error
}
}
};
func would not be virtual. It is just a template policy that deriving from IService needs to have a func(Thing<T>*) method.
Maybe some interface for the Thing would do the trick?
class IThing { };
template< typename T>
class Thing: public IThing { };
class IService {
public:
virtual void func(IThing* arg) = 0;
};
template< typename T>
class Service: public IService {
virtual void func(IThing* arg) {
Thing<T> *thing = dynamic_cast<Thing<T> *>(arg);
if (thing) {
// implementation
}
}
};
I'm assuming you want to type-erase Thing's <T> template parameter through the use of a non-templated IService class and that you do not care about T in the implementation of IService. I am not sure these assumption are correct, but here's a possible solution.
I'm also assuming that having virtual dispatch inside Thing suffice in your use case.
// Create a `ThingBase` class to "type-erase" `Thing`'s
// template parameter. `ThingBase` should contain your
// `func`, as `virtual`.
struct ThingBase
{
virtual void func();
};
// Your `Thing<T>` class should override `func`
template <typename T>
struct Thing : ThingBase
{
void func() override { /* ... */ }
};
// Your `IService` now only needs to be as follows:
struct IService
{
void func(ThingBase& x)
{
x.func();
}
};
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
}
};
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
};