Take, for example, the following code:
// Say I have this class defined in some other file
class Foo;
// This class will act as a wrapper for an integer map
// to function pointers, which will create type TFoo objects
// depending on the given input (in this case a "const char*"
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_;
};
// Now, this class will receive an _object_ of type
// "const Bar<T>&", which will have an already initialized
// map of integers to function pointers, different
// functions will be called with different input values
// via the public method, "action()".
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())
{
// no handler defined for int `a'
return TFoo();
}
// i.e. CBar.handlers_[a](x)
return it->second(x);
}
private:
const Bar<TFoo>& bar_;
};
// Here is how the map of integers to function pointers
// will be initialized...
static std::unordered_map<int, Foo (*)(const char*)> handlers
{
{ 0, _hdl_0 }, // _hdl_* functions defined in different file
{ 1, _hdl_1 },
{ 2, _hdl_2 }
};
// And then passed to a "const Bar<T>" type object here
const Bar<Foo> bar (handlers);
int main()
{
// --> HERE IS WHAT I WANT TO CHANGE <--
Quux<decltype(bar)::foo_t, bar> quux;
// -------------------------------------
// Example (trivial) use of the 'quux' object
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;
return 0;
}
Notice that the 'Quux' class takes two template parameters - one that is also a template parameter for the 'Bar' class, and a reference to a template object of type const Bar<T>
, where T is any class related to 'Foo'. I would like to be able to do the following instead:
Quux<bar> quux;
'bar' is an object of type Bar<Foo>
, but it should also be able to be any Bar<T>
type. 'bar'是Bar<Foo>
类型的对象,但它也应该可以是任何Bar<T>
类型。
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;
I'm passing in a reference to an object to 'Quux' as a template parameter because copying would be inefficient (I think), rather than making a copy of the entire foo_handler_map_t
object. I just want to be able to have a bunch of objects of type const Bar<T>
that are defined globally in some namespace, and to be able to initialize 'Quux' objects like so:
namespace blah
{
std::unordered_map<int, /* funcptr type 0 */> _funcmap_0 { ... }
std::unordered_map<int, /* funcptr type 1 */> _funcmap_1 { ... }
...
const Bar<Foo0> FSET0 (_funcmap_0);
const Bar<Foo1> FSET1 (_funcmap_1);
...
}
int main()
{
Quux<blah::FSET0> a;
Quux<blah::FSET1> b;
...
return 0;
}
...And I do NOT want to pass it as a constructor argument.
The comments are very useful. However, if you wish to reduce the number of template arguments, you can pass the CBar
as an argument to the constructor:
template<class TFoo>
class Quux
{
public:
Quux(const Bar<TFoo>& CBar)
: 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_;
};
And define a function to create an instance of Quux
:
template <typename TFoo>
auto make_Quux(const Bar<TFoo>& bar)
{
return Quux<TFoo>(bar);
}
Then in main()
, you can use make_Quux()
:
int main()
{
auto quux = make_Quux(bar);
//...
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.