Возьмет, к примеру, следующий код:Как передать шаблон шаблона шаблону в класс шаблона без базового параметра шаблона?
// 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;
}
Обратите внимание, что класс в «Quux» принимает два параметра шаблона - один, который также является параметр шаблона для класса «Bar», и ссылка на шаблон объект типа const Bar<T>
, где T - любой класс, относящийся к «Foo». Я хотел бы быть в состоянии сделать следующий вместо:
Quux<bar> quux;
Примечания: «бар» является объектом типа Bar<Foo>
, но он также должен быть в состоянии быть любым Bar<T>
типа.
Возможно ли это? Я думал, что может быть что-то вроде ниже, могут быть использованы в качестве быстрого решения проблемы, но я не могу понять, что поставить вместо /* ??? */
:
template<const Bar</* ??? */>& CBar>
using Nuff = Quux<decltype(CBar)::foo_t, CBar>
Nuff<bar> nuff;
EDIT
Я передавая ссылку на объект в «Quux» в качестве параметра шаблона, потому что копирование будет неэффективным (я думаю), вместо того, чтобы делать копию всего объекта foo_handler_map_t
. Я просто хочу, чтобы иметь возможность иметь кучу объектов типа const Bar<T>
, которые определены глобально в некотором пространстве имен, и, чтобы иметь возможность инициализировать объекты «» Quux так:
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;
}
... И я не хотите передать его как аргумент конструктора.
Что это 'шаблон <класс Тьфу, Const Bar & сантибар>' ? Поскольку вы указываете, что оно компилируется, я предполагаю, что оно действительно так же, как указатель на некоторый внешний объект. Но какова цель здесь, чего вы пытаетесь достичь? –
Было бы неплохо, если бы вы смогли значительно сократить свой пример. Пожалуйста, предоставьте минимальный код, который нам нужен, чтобы уловить ваш вопрос! – Klaus
Это невозможно в текущем C++, будет возможно сразу после [n4469] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4469.html). –