Take, for example, the following code:
#include <iostream>
#include <string>
#include <unordered_map>
class Foo
{
public:
Foo()
{
}
Foo(const std::string& baz)
: baz_(baz)
{
}
virtual ~Foo()
{
}
const std::string& baz() const
{
return this->baz_;
}
private:
std::string baz_;
};
template<class TFoo>
struct Bar
{
typedef TFoo foo_t;
typedef TFoo (*get_foo_f_t)(const char*);
typedef std::unordered_map<int, get_foo_f_t> foo_handler_map_t;
Bar(const foo_handler_map_t& handlers)
: handlers_(handlers)
{
}
~Bar()
{
}
const foo_handler_map_t& handlers_;
};
template<class TFoo, const Bar<TFoo>& CBar>
class Quux
{
public:
Quux()
: bar_(CBar)
{
}
~Quux()
{
}
TFoo action(int a, const char* x)
{
auto it = this->bar_.handlers_.find(a);
if (it == this->bar_.handlers_.end())
{
return TFoo();
}
return it->second(x);
}
private:
const Bar<TFoo>& bar_;
};
Foo _hdl_0(const char* x)
{
return Foo(std::string("HDL #0 ") + x);
}
Foo _hdl_1(const char* x)
{
return Foo(std::string("HDL #1 ") + x);
}
Foo _hdl_2(const char* x)
{
return Foo(std::string("HDL #2 ") + x);
}
static std::unordered_map<int, Foo (*)(const char*)> handlers
{
{ 0, _hdl_0 },
{ 1, _hdl_1 },
{ 2, _hdl_2 }
};
const Bar<Foo> bar (handlers);
int main()
{
Quux<decltype(bar)::foo_t, bar> quux;
std::cout << quux.action(0, "abc").baz() << std::endl;
std::cout << quux.action(1, "def").baz() << std::endl;
std::cout << quux.action(2, "ghi").baz() << std::endl;
std::cout << std::endl;
std::cout << quux.action(2, "abc").baz() << std::endl;
std::cout << quux.action(0, "def").baz() << std::endl;
std::cout << quux.action(1, "ghi").baz() << std::endl;
std::cout << std::endl;
std::cout << quux.action(1, "abc").baz() << std::endl;
std::cout << quux.action(2, "def").baz() << std::endl;
std::cout << quux.action(0, "ghi").baz() << std::endl;
return 0;
}
Notice that the 'Quux' class takes two template parameters - one that is also a template parameter for the 'Bar' class, and the template 'Bar' class itself. I would like to be able to do the following instead:
Quux<bar> quux;
Note: 'bar' is an object of type Bar<Foo>
, but it should also be able to be any Bar<T>
type.
Is this possible? I was thinking that maybe something like below could be used as a quick workaround, but I can't figure out what to put in place of /* ??? */
:
template<const Bar</* ??? */>& CBar>
using Nuff = Quux<decltype(CBar)::foo_t, CBar>
Nuff<bar> nuff;
Aucun commentaire:
Enregistrer un commentaire