hamsterman wrote: |
---|
Neat. I'm not sure I know where that could be used, but still, neat. |
Thanx! ^^ Neither do I know where it can be used, I wrote it just for fun :D
hamsterman wrote: |
---|
One question though. What's template <class T, template <class> class Cb> ? Does it mean that the second class has to be a template class? Would template <class T, class Cb> not work? It seems logical to allow a not type specific Callback to me. |
Yeah, I should probably have said that earlier. I tried something like this at first:
1 2
|
template <class T, class Cb>
Visitor & AddCb(const Cb & cb);
|
But then I had to do something like this in main...
1 2 3 4
|
do_it.
AddCb<int>(DoIt<int>()).
AddCb<double>(DoIt<double>()).
AddCb<std::string>(DoIt<std::string>());
|
If I make Cb a template class, I don't need to specify the type twice. That's why I did it.
hamsterman wrote: |
---|
Maybe you could make Callback a template class? |
This is actually a very interesting idea. I guess I could keep my Callback as it is and also add a template subclass CallbackT. Then, in main, I could derive my concrete callbacks either from Callback or from CallbackT. Ok, while typing this I stopped for a while and started coding and I got this and it works:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
//...
template <class T>
struct CallbackT : public Callback {};
//...
template <class T, class Cb>
Visitor & AddCb(const Cb & cb);
template <class T, template <class> class Cb>
Visitor & AddCb(const Cb<T> & cb);
//...
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
//...
template <class T>
struct DoIt : public Visitor::Callback
{
void operator()(void * data) {std::cout << *(T*)data << std::endl;}
DoIt * clone() const {return new DoIt<T>;}
};
struct DoItInt : public Visitor::CallbackT<int>
{
void operator()(void * data) {std::cout << *(int*)data+100 << std::endl;}
DoItInt * clone() const {return new DoItInt;}
};
struct DoItChar : public Visitor::CallbackT<char>
{
void operator()(void * data) {std::cout << char(*(char*)data+1) << std::endl;}
DoItChar * clone() const {return new DoItChar;}
};
//...
obj_vec.push_back(std::string("asdf"));
obj_vec.push_back(1);
obj_vec.push_back(1.1);
obj_vec.push_back(2);
obj_vec.push_back(2.2);
obj_vec.push_back('A');
//...
do_it.
AddCb<int>(DoItInt()).
AddCb<char>(DoItChar()).
AddCb(DoIt<double>()).
AddCb(DoIt<std::string>());
//...
|
I lose the << operator syntax though, but I don't really care.
The annoying thing was having to write the type twice.
Thanks for the feedback! :)