Template type deduction with a non-copyable class - c++

Suppose I have an autolocker class which looks something like this:
template <T>
class autolocker {
public:
autolocker(T *l) : lock(l) {
lock->lock();
}
~autolocker() {
lock->unlock();
}
private:
autolocker(const autolocker&);
autolocker& operator=(const autolocker&);
private:
T *lock;
};
Obviously the goal is to be able to use this autolocker with anything that has a lock/unlock method without resorting to virtual functions.
Currently, it's simple enough to use like this:
autolocker<some_lock_t> lock(&my_lock); // my_lock is of type "some_lock_t"
but it is illegal to do:
autolocker lock(&my_lock); // this would be ideal
Is there anyway to get template type deduction to play nice with this (keep in my autolocker is non-copyable). Or is it just easiest to just specify the type?

Yes you can use the scope-guard technique
struct autolocker_base {
autolocker_base() { }
protected:
// ensure users can't copy-as it
autolocker_base(autolocker_base const&)
{ }
autolocker_base &operator=(autolocker_base const&)
{ return *this; }
};
template <T>
class autolocker : public autolocker_base {
public:
autolocker(T *l) : lock(l) {
lock->lock();
}
autolocker(const autolocker& o)
:autolocker_base(o), lock(o.lock)
{ o.lock = 0; }
~autolocker() {
if(lock)
lock->unlock();
}
private:
autolocker& operator=(const autolocker&);
private:
mutable T *lock;
};
Then write a function creating the autolocker
template<typename T>
autolocker<T> makelocker(T *l) {
return autolocker<T>(l);
}
typedef autolocker_base const& autolocker_t;
You can then write it like this:
autolocker_t lock = makelocker(&my_lock);
Once the const reference goes out of scope, the destructor is called. It doesn't need to be virtual. At least GCC optimizes this quite well.
Sadly, this means you have to make your locker-object copyable since you need to return it from the maker function. But the old object won't try to unlock twice, because its pointer is set to 0 when it's copied, so it's safe.

Obviously you can't get away with autolocker being a template, because you want to use it as a type, and templates must be instantiated in order to obtain types.
But type-erasure might be used to do what you want. You turn the class template into a class and its constructor into a member template. But then you'd have to dynamically allocate an inner implementation object.
Better, store a pointer to a function that performs the unlock and let that function be an instance of a template chosen by the templatized constructor. Something along these lines:
// Comeau compiles this, but I haven't tested it.
class autolocker {
public:
template< typename T >
autolocker(T *l) : lock_(l), unlock_(&unlock<T>) { l->lock(); }
~autolocker() { unlock_(lock_); }
private:
autolocker(const autolocker&);
autolocker& operator=(const autolocker&);
private:
typedef void (*unlocker_func_)(void*);
void *lock_;
unlocker_func_ unlock_;
template <typename T>
static void unlock(void* lock) { ((T*)lock)->unlock(); }
};
I haven't actually tried this and the syntax might be wrong (I'm not sure how to take the address of a specific function template instance), but I think this should be doable in principle. Maybe someone comes along and fixes what I got wrong.
I like this a lot more than the scope guard, which, for some reason, I never really liked at all.

I think jwismar is correct and what you want is not possible with C++. However, a similar (not direct analogue) construct is possible with C++0x, using several new features (rvalues/moving and auto variable type):
#include <iostream>
template <typename T>
class autolocker_impl
{
public:
autolocker_impl(T *l) : lock(l) {
lock->lock();
}
autolocker_impl (autolocker_impl&& that)
: lock (that.lock)
{
that.lock = 0;
}
~autolocker_impl() {
if (lock)
lock->unlock();
}
private:
autolocker_impl(const autolocker_impl&);
autolocker_impl& operator=(const autolocker_impl&);
private:
T *lock;
};
template <typename T>
autolocker_impl <T>
autolocker (T* lock)
{
return autolocker_impl <T> (lock);
}
struct lock_type
{
void lock ()
{ std::cout << "locked\n"; }
void unlock ()
{ std::cout << "unlocked\n"; }
};
int
main ()
{
lock_type l;
auto x = autolocker (&l);
}

autolocker is a class template, not a class. Your "this would be ideal" is showing something that doesn't make sense in C++.

Related

Bypass a template error with a private destructor

In compile time, I've got the following issue, how to make this compile, because conceptually for me it's correct, any suggestions of refactoring are welcome.
I got a compile error because "Search" destructor is private but I won't use delete on a Search pointer since I provided a custom Deleter in the initialization of the base class. I know that the compiler doesn't know that, how to bypass it.
error description :
error C2248: cannot access private member declared in class 'Search'
compiler has generated 'Search::~Search' here
class Search
{
public:
static Search* New(/* */); // using a pool of already allocated objects to avoid expensive allocations
static void Delete(Search*);
private:
Search(/* */) {/* */}
~Search() {/* */}
};
template<class T>
class MyList
{
public:
typedef (*CustomDeleter) (T* pElement);
MyList(CustomDeleter lpfnDeleter = NULL) {};
void Empty()
{
for (/**/)
{
if (m_pList[m_nListLastUsed])
{
if (m_lpfnCustomDeleter == NULL)
delete m_pList[m_nListLastUsed]; // COMPILE ERROR HERE BECAUSE Search destructor is private BUT I won't use that instruction since
// I provided a custom Deletern I know that the compiler doesn't know that, how to bypass it
else
m_lpfnCustomDeleter(m_pList[m_nListLastUsed]);
}
}
}
private:
T** m_pList;
CustomDeleter m_lpfnCustomDeleter; // Pointer to a custom deleter
};
class Query : public MyList<Search>
{
public:
Query() : MyList<Search>(&Search::Delete) // I set a custom deleter since Search hides its destructor : is this the right way ?
{}
~Query()
{
/****/
Empty(); // PROBLEM HERE
/***/
}
};
Make sure that 'm_lpfnCustomDeleter' is never NULL or better nullptr. You can make sure of this by falling back to a default 'deleter' if the user does not provide with any custom deleter.
I would prefer something like below.
#include <iostream>
template <typename PointerType>
struct DefaultDeleter {
void operator()(PointerType* ptr) {
std::cout << "Delete\n";
}
};
struct CustomDeleter {
void operator()(int* ptr) {
std::cout << "Custom int deleter" << std::endl;
}
};
template <typename T, typename Deleter = DefaultDeleter<T>>
class Whatever
{
public:
Whatever() {
std::cout << "Cons\n";
}
void deinit() {
Deleter d;
auto v = new T;
d(v); // Just for the sake of example
}
};
int main() {
Whatever<char> w;
w.deinit();
Whatever<int, CustomDeleter> w2;
w2.deinit();
return 0;
}
Updated :: W/o code refactoring
Assuming w/o c++11
Have this small metaprogram added to your code base.
namespace my {
template <typename T, typename U> struct is_same {
static const bool value = false;
};
template <typename T>
struct is_same<T, T> {
static const bool value = true;
};
template <bool v, typename T = void> struct enable_if;
template <typename T = void> struct<true, T> {
typedef T type;
};
}
Change your Empty function to:
void Empty() {
for (/****/) {
do_delete();
}
}
template <typename =
typename my::enable_if<my::is_same<T, Search>::value>::type>
void do_delete() {
assert (m_lpfnCustomDeleter != NULL);
m_lpfnCustomDeleter(m_pList[m_nListLastUsed]);
}
void do_delete() {
delete m_pList[m_nListLastUsed];
}
If you are using c++11, the you dont have to write the metaprogram under namespace 'my'. Just replace 'my::is_same' and 'my::enable_if' with 'std::is_same' and 'std::enable_if'.
Note:, Have not compiled and tested the above code.
Separate the code doing the deleting from the rest:
if (m_pList[m_nListLastUsed])
{
if (m_lpfnCustomDeleter == NULL)
delete m_pList[m_nListLastUsed]; // COMPILE ERROR HERE BECAUSE Search destructor is private BUT I won't use that instruction since
// I provided a custom Deletern I know that the compiler doesn't know that, how to bypass it
else
m_lpfnCustomDeleter(m_pList[m_nListLastUsed]);
}
Replace the code above by a call to:
custom_delete(m_pList[m_nListLastUsed]);
Then add it as a method of your list class, don't forget to include <type_traits> as well:
std::enabled_if<std::is_destructible<T>::value, void>::type custom_delete(T* ptr) {
/* Note: this isn't pre-2000 anymore, 'lpfn' as a prefix is horrible,
don't use prefixes! */
if (m_lpfnCustomDeleter) {
m_lpfnCustomDeleter(ptr);
} else {
delete ptr;
}
}
std::enabled_if<!std::is_destructible<T>::value, void>::type custom_delete(T* ptr) {
if (!m_lpfnCustomDeleter) {
throw "No custom deleter for a non destructible type!";
}
m_lpfnCustomDeleter(ptr);
}
enabled_if will make it so that the function where it can delete the object directly doesn't exist in your list if the object has a private destructor.
Alternatively, you could pass a structure (or function) acting as a custom deleter as the second template argument of your list with a default value as one that calls the delete operator, then directly call this structure on your pointer, as in Arunmu's anser.

C++ Template : one list by class, how to factorize the code?

Suppose I have this class :
class Component1;
class Component2;
// many different Components
class Component42;
class MyClass
{
public:
MyClass(void) {};
std::list<Component1> component1List;
std::list<Component2> component2List;
// one list by component
std::list<Component42> component42List;
};
I would like to create a function with the following signature:
template<class T> void addElement(T component);
It should do the following:
if component is of type Component1, add it to Component1List
if component is of type Component2, add it to Component2List, etc.
Is it possible? What's a good way to do this?
I can obtain the same behaviour with a function like :
template<class T> void addElement(int componentType, T component);
but I'd rather not have to specify the componentType like this : it's useless information and it open the door to possible errors (if componentType doesn't represent the type of component).
std::tuple to the rescue.
changelog:
use std::decay_t
added the variadic argument form
add_component() now returns a reference to this to allow call-chaining.
#include <iostream>
#include <list>
#include <utility>
#include <type_traits>
#include <tuple>
class Component1 {};
class Component2 {};
struct Component3 {
Component3() {}
};
// many different Components
template<class...ComponentTypes>
class MyClassImpl
{
template<class Component> using list_of = std::list<Component>;
public:
using all_lists_type =
std::tuple<
list_of<ComponentTypes> ...
>;
// add a single component
template<class Component>
MyClassImpl& add_component(Component&& c)
{
list_for<Component>().push_back(std::forward<Component>(c));
return *this;
}
// add any number of components
template<class...Components>
MyClassImpl& add_components(Components&&... c)
{
using expand = int[];
void(expand { 0, (void(add_component(std::forward<Components>(c))), 0)... });
return *this;
}
template<class Component>
auto& list_for()
{
using component_type = std::decay_t<Component>;
return std::get<list_of<component_type>>(_lists);
}
template<class Component>
const auto& list_for() const
{
using component_type = std::decay_t<Component>;
return std::get<list_of<component_type>>(_lists);
}
private:
all_lists_type _lists;
};
using MyClass = MyClassImpl<Component1, Component2, Component3>;
int main()
{
MyClass c;
c.add_component(Component1());
c.add_component(Component2());
const Component3 c3;
c.add_component(c3);
c.add_components(Component1(),
Component2(),
Component3()).add_components(Component3()).add_components(Component1(),
Component2());
std::cout << c.list_for<Component1>().size() << std::endl;
return 0;
}
The most straightforward variant is to simply not use templates but to overload the addElement() function:
void addElement(Component1 element)
{
this->element1List.push_back(element);
}
void addElement(Component2 element)
{
this->element2List.push_back(element);
}
// ... etc
However, this might get tedious if you have many of these (and you don't just have addElement(), I guess). Using a macro to generate the code for each type could still do the job with reasonable effort.
If you really want to use templates, you could use a template function and specialize the template function for each type. Still, this doesn't reduce the amount of code repetition when compared with the above approach. Also, you could still reduce it using macros to generate the code.
However, there's hope for doing this in a generic way. Firstly, let's create a type that holds the list:
template<typename T>
struct ComponentContainer
{
list<T> componentList;
};
Now, the derived class just inherits from this class and uses C++ type system to locate the correct container baseclass:
class MyClass:
ComponentContainer<Component1>,
ComponentContainer<Component2>,
ComponentContainer<Component3>
{
public:
template<typename T>
void addElement(T value)
{
ComponentContainer<T>& container = *this;
container.componentList.push_back(value);
}
}
Notes here:
This uses private inheritance, which is very similar to the containment you originally used.
Even though ComponentContainer is a baseclass, it doesn't have any virtual functions and not even a virtual destructor. Yes, this is dangerous and should be documented clearly. I wouldn't add a virtual destructor though, because of the overhead it has and because it shouldn't be needed.
You could drop the intermediate container altogether and derive from list<T>, too. I didn't because it will make all of list's memberfunctions available in class MyClass (even if not publicly), which might be confusing.
You can't put the addElement() function into the base class template to avoid the template in the derived class. The simple reason is that the different baseclasses are scanned in order for a addElement() function and only then overload resolution is performed. The compiler will only find the addElement() in the first baseclass therefore.
This is a plain C++98 solution, for C++11 I'd look at the type-based tuple lookup solutions suggested by Jens and Richard.
If there are not too many classes you could go with overloading. A template-based solution could be done with type-based lookup for tuples:
class MyClass {
public:
template<typename T> void addElement(T&& x) {
auto& l = std::get<std::list<T>>(lists);
l.insert( std::forward<T>(x) );
}
private:
std::tuple< std::list<Component1>, std::list<Component2> > lists;
};
If you don't know in advance the types you will need storing when instantiating the multi-container an option is to hide the types and using type_index to keep a map of lists:
struct Container {
struct Entry {
void *list;
std::function<void *(void*)> copier;
std::function<void(void *)> deleter;
};
std::map<std::type_index, Entry> entries;
template<typename T>
std::list<T>& list() {
Entry& e = entries[std::type_index(typeid(T))];
if (!e.list) {
e.list = new std::list<T>;
e.deleter = [](void *list){ delete ((std::list<T> *)list); };
e.copier = [](void *list){ return new std::list<T>(*((std::list<T> *)list)); };
}
return *((std::list<T> *)e.list);
}
~Container() {
for (auto& i : entries) i.second.deleter(i.second.list);
}
Container(const Container& other) {
// Not exception safe... se note
for (auto& i : other.entries) {
entries[i.first] = { i.second.copier(i.second.list),
i.second.copier,
i.second.deleter };
}
};
void swap(Container& other) { std::swap(entries, other.entries); }
Container& operator=(const Container& other) {
Container(other).swap(*this);
return *this;
};
Container() { }
};
that can be used as:
Container c;
c.list<int>().push_back(10);
c.list<int>().push_back(20);
c.list<double>().push_back(3.14);
NOTE: the copy constructor as written now is not exception safe because in case a copier throws (because of an out of memory or because a copy constructor of an element inside a list throws) the already allocated lists will not be deallocated.
void addElement(Component1 component) {
componentList1.insert(component);
}
void addElement(Component2 component) {
componentList2.insert(component);
}

gcnew operator for generic type

I have the following simple class
generic<typename T> where T:IDbConnection ref class CDbConnection
{
private:
IDbConnection^m_db;
ConnectionState^ m_originalConnState;
public:
CDbConnection();
bool Connect(String ^ connStr);
bool Exists(int id);
auto GetAllData(String^ tableStr);
~CDbConnection();
!CDbConnection();
};
and here is my constructor
generic<typename T> CDbConnection<T>::CDbConnection()
{
m_db=gcnew T();
m_originalConnState=m_db->State;
}
But the compiler complains <1> the gcnew T() can't be used for generic type
<2> auto key in use is wrong as the function expects a trailing return type
Thank you for your reading and replies
I forgot this
where T:IDbConnection, gcnew()
which is exactly the same as C# generics
to get rid of the gcnew error as stated above.
In order to achieve genericity, you must change your class definition to
generic<typename T> where T:IDbConnection ref class CDbConnection
{
private:
T m_db;
ConnectionState^ m_originalConnState;
public:
CDbConnection();
bool Connect(String ^ connStr);
bool Exists(int id);
auto GetAllData(String^ tableStr);
~CDbConnection();
!CDbConnection();
};
As you are already constraining your T to be at least IDbConnection it can't be anything else.
Then your constructor
generic<typename T> CDbConnection<T>::CDbConnection()
{
m_originalConnState=m_db.State;
}
should work like you intended.
EDIT
It seems you cannot declare a reference to a generic. If you assign the object to the stack it will work.
See this entry.
// C3229.cpp
// compile with: /clr /c
generic <class T>
ref class C {
T^ t; // C3229
};
// OK
generic <class T>
ref class D {
T u;
};

C++ Push Multiple Types onto Vector

Note: I know similar questions to this have been asked on SO before, but I did not find them helpful or very clear.
Second note: For the scope of this project/assignment, I'm trying to avoid third party libraries, such as Boost.
I am trying to see if there is a way I can have a single vector hold multiple types, in each of its indices. For example, say I have the following code sample:
vector<something magical to hold various types> vec;
int x = 3;
string hi = "Hello World";
MyStruct s = {3, "Hi", 4.01};
vec.push_back(x);
vec.push_back(hi);
vec.push_back(s);
I've heard vector<void*> could work, but then it gets tricky with memory allocation and then there is always the possibility that certain portions in nearby memory could be unintentionally overridden if a value inserted into a certain index is larger than expected.
In my actual application, I know what possible types may be inserted into a vector, but these types do not all derive from the same super class, and there is no guarantee that all of these types will be pushed onto the vector or in what order.
Is there a way that I can safely accomplish the objective I demonstrated in my code sample?
Thank you for your time.
The objects hold by the std::vector<T> need to be of a homogenous type. If you need to put objects of different type into one vector you need somehow erase their type and make them all look similar. You could use the moral equivalent of boost::any or boost::variant<...>. The idea of boost::any is to encapsulate a type hierarchy, storing a pointer to the base but pointing to a templatized derived. A very rough and incomplete outline looks something like this:
#include <algorithm>
#include <iostream>
class any
{
private:
struct base {
virtual ~base() {}
virtual base* clone() const = 0;
};
template <typename T>
struct data: base {
data(T const& value): value_(value) {}
base* clone() const { return new data<T>(*this); }
T value_;
};
base* ptr_;
public:
template <typename T> any(T const& value): ptr_(new data<T>(value)) {}
any(any const& other): ptr_(other.ptr_->clone()) {}
any& operator= (any const& other) {
any(other).swap(*this);
return *this;
}
~any() { delete this->ptr_; }
void swap(any& other) { std::swap(this->ptr_, other.ptr_); }
template <typename T>
T& get() {
return dynamic_cast<data<T>&>(*this->ptr_).value_;
}
};
int main()
{
any a0(17);
any a1(3.14);
try { a0.get<double>(); } catch (...) {}
a0 = a1;
std::cout << a0.get<double>() << "\n";
}
As suggested you can use various forms of unions, variants, etc. Depending on what you want to do with your stored objects, external polymorphism could do exactly what you want, if you can define all necessary operations in a base class interface.
Here's an example if all we want to do is print the objects to the console:
#include <iostream>
#include <string>
#include <vector>
#include <memory>
class any_type
{
public:
virtual ~any_type() {}
virtual void print() = 0;
};
template <class T>
class concrete_type : public any_type
{
public:
concrete_type(const T& value) : value_(value)
{}
virtual void print()
{
std::cout << value_ << '\n';
}
private:
T value_;
};
int main()
{
std::vector<std::unique_ptr<any_type>> v(2);
v[0].reset(new concrete_type<int>(99));
v[1].reset(new concrete_type<std::string>("Bottles of Beer"));
for(size_t x = 0; x < 2; ++x)
{
v[x]->print();
}
return 0;
}
In order to do that, you'll definitely need a wrapper class to somehow conceal the type information of your objects from the vector.
It's probably also good to have this class throw an exception when you try to get Type-A back when you have previously stored a Type-B into it.
Here is part of the Holder class from one of my projects. You can probably start from here.
Note: due to the use of unrestricted unions, this only works in C++11. More information about this can be found here: What are Unrestricted Unions proposed in C++11?
class Holder {
public:
enum Type {
BOOL,
INT,
STRING,
// Other types you want to store into vector.
};
template<typename T>
Holder (Type type, T val);
~Holder () {
// You want to properly destroy
// union members below that have non-trivial constructors
}
operator bool () const {
if (type_ != BOOL) {
throw SomeException();
}
return impl_.bool_;
}
// Do the same for other operators
// Or maybe use templates?
private:
union Impl {
bool bool_;
int int_;
string string_;
Impl() { new(&string_) string; }
} impl_;
Type type_;
// Other stuff.
};

How can I create a type based lookup table in order to implement multiple-dispatch in C++?

I'm attempting to make a messaging system in which any class derived from "Messageable" can receive messages based on how the function handleMessage() is overloaded. For example:
class Messageable {
public:
void takeMessage(Message& message) {
this->dispatchMessage(message);
}
protected:
void bindFunction(std::type_info type, /* Need help here */ func) {
m_handlers[type] = func;
}
void dispatchMessage(Message& message) {
m_handlers[typeid(message)](message);
}
private:
std::map<std::type_info, /*Need help here*/ > m_handlers;
};
class TestMessageable : public Messageable {
public:
TestMessageable() {
this->bindFunction(
typeid(VisualMessage),
void (TestMessageable::*handleMessage)(VisualMessage));
this->bindFunction(
typeid(DanceMessage),
void (TestMessageable::*handleMessage)(DanceMessage));
}
protected:
void handleMessage(VisualMessage visualMessage) {
//Do something here with visualMessage
}
void handleMessage(DanceMessage danceMessage) {
//Do something here with danceMessage
}
};
In a nutshell I want the correct version of handleMessage to be called based on the RTTI value of any given message.
How can I implement this preferably without some sort of monolithic switch/case statement.
You should look into the Double Dispatch pattern. See information here.
You should be able to implement VisualMessage as a class like such:
class VisualMessage : public Message
{
public:
virtual void dispatch(Messageable & inMessageable)
{
inMessageable.handleMessage(*this);
}
};
and then call it like this:
Message & vMessage = VisualMessage();
Messageable & tMessageable = TestMessageable();
vMessage.dispatch(tMessageable);
It will then call TestMessageable::handleMessage(VisualMessage & visualMessage)
This is because Message::dispatch will be based on the VisualMessage type. Then when VisualMessage::dispatch calls inMessageable.handleMessage(*this) it will call the right handleMessage because the type of the *this pointer is VisualMessage, not Message.
To fix your code:
struct CompareTypeInfo
: std::binary_function<const std::type_info*, const std::type_info*, bool>
{
bool operator()(const std::type_info* a, const std::type_info* b) {
return a->before(*b);
}
};
class Messageable
{
protected:
typedef void (*handlefn)(Messageable *, Message &);
void bindFunction(const std::type_info& type, handlefn func) {
m_handlers[&type] = func;
}
void dispatchMessage(Message& message) {
m_handlers[&typeid(message)](this, message);
}
template <typename S, typename T>
static void handle(Messageable *self, Message &m) {
static_cast<S*>(self)->handleMessage(static_cast<T&>(m));
}
private:
std::map<const std::type_info*, handlefn, CompareTypeInfo> m_handlers;
};
class TestMessageable : public Messageable
{
public:
TestMessageable()
{
this->bindFunction(
typeid(VisualMessage), &Messageable::handle<TestMessageable,VisualMessage>);
this->bindFunction(
typeid(DanceMessage), &Messageable::handle<TestMessageable,DanceMessage>);
}
public:
void handleMessage(VisualMessage visualMessage)
{
//Do something here with visualMessage
}
void handleMessage(DanceMessage danceMessage)
{
//Do something here with danceMessage
}
}
};
Those static_casts could be dynamic_casts for "extra safety" (assuming there are virtual functions kicking around). But the design means you know self must be a pointer to S, because otherwise it wouldn't have this function registered to it, and you know m must refer to a T, because its typeid has already been checked in dispatchMessage. So a failed cast can't happen if the class is used correctly, and all you can do if it does happen is debug.
Actually I think you could cut down the verbiage a bit more by making bindFunction a template too:
template <typename S, typename T>
void bindFunction(void)
{
m_handlers[&typeid(T)] = handle<S,T>;
}
Then call it with:
this->bindFunction<TestMessageable,VisualMessage>();
But still, you can see why Steve Rowe's double dispatch code is usually preferred...
This is an old question but the NUClear library is designed to provide fast and type-safe message passing in a similar vein to the original intent of this question.
Full Disclosure: I am one of the co-developers of NUClear
In this case the TestMessageable class is implemented as a NUClear::Reactor like so:
#include <NUClear.h>
// TestMessageable.h
class TestMessageable : NUClear::Reactor {
public:
TestMessageable(NUClear::PowerPlant* powerPlant);
private:
};
// TestMessageable.cpp
#include "TestMessageable.h"
TestMessageable::TestMessageable(NUClear::PowerPlant* powerPlant)
: NUClear::Reactor(powerPlant) {
on<Trigger<VisualMessage>>([this](const VisualMessage& message) {
// Do something with VisualMessage here
// On can also take anything that is callable with a const& VisualMessage.
// Messages are sent using emit.
// If you don't have C++14 NUClear provides std::make_unique
auto classifiedData = std::make_unique<ClassifiedVision>(/* stuff */);
emit(std::move(classifieData));
});
on<Trigger<DanceMessage>>([this](const DanceMessage& message) {
// Do something with DanceMessage here.
});
}
You will find such kind of implementation in Scott Meyers' More Effective C++ and
item - 31 is what you want & nicely explained.