Я предполагаю, что некоторые другие люди сталкивались с этой проблемой проектирования раньше, поэтому я надеюсь, что кто-то мог бы дать мне несколько советов о том, что делать: у меня есть класс, который должен содержать частный универсальный объект. Насколько я могу судить, я не могу уйти, не сделав весь класс шаблоном. FINE. Но теперь, есть ли способ вывести тип базового объекта во время конструирования из параметра конструктора, не указав его явно (я хочу опустить параметр шаблона, Derived
когда я создаю Test
учебный класс):
#include <iostream>
template <typename T>
class Generic
{
};
class Derived : public Generic<int>
{
public:
Derived ();
int GetFoo ();
private:
int m_foo;
};
template <typename T>
class Test
{
public:
Test (T &underlying);
private:
T m_underlying;
};
Derived::Derived ()
{
this->m_foo = 666;
}
int Derived::GetFoo ()
{
return this->m_foo;
}
template<typename T>
Test<T>::Test (T &underlying) : m_underlying(underlying)
{
std::cout << this->m_underlying.GetFoo() << std::endl;
}
int main ()
{
Derived underlying;
Test<Derived> test(underlying);
return 0;
}
Есть ли какая-то другая стратегия дизайна, о которой я должен знать, чтобы достичь своей цели?
Обычно у вас есть шаблон класса вместе с выводом типа функция шаблон:
template <typename T>
struct Foo
{
Foo(T const &);
};
template <typename T>
Foo<T> make_foo(T const & t)
{
return Foo<T>(t);
}
Использование:
auto foo = make_foo(1728); // makes a Foo<int>
Эта идея используется бесчисленное количество раз в стандартной библиотеке (например, make_pair
, make_tuple
, make_shared
). Руководящий принцип заключается в том, что вы должны произносить желаемое имя типа не более одного раза, а не вообще, если оно может быть выведено.
Просто сделайте функцию для создания Test
объект:
template <typename T>
Test<T> make_test(T& underlying)
{
return Test<T>(underlying);
}
int main ()
{
Derived underlying;
auto test = make_test(underlying);
return 0;
}