Я работаю над шаблоном проектирования конвейера/потока данных. У меня есть класс вывода данных алгоритма (AlgorithmOutput
), который служит интерфейсом между двумя связанными сегментами сети. В частности, он предоставляет набор шаблонов методов getOutput<size_t N>
, которые используются для данных, выводимых из объекта «передатчик данных».C++ Специализация частичного шаблона - упрощение дизайна
Текущий дизайн основан на идее, что пользователи получают класс AlgorithmOutput
и предоставляют конечное число реализаций шаблона метода getOutput<size_t N>
. Я также должен иметь возможность разрешать пользователям предоставлять свои собственные типы возвращаемых данных из метода getOutput
(т. Е. Тип возврата не может быть полиморфным). Кроме того, необходимо иметь все реализации getOutput
, чтобы иметь возможность доступа к тому же набору данных, который определен как член класса, к которому относятся методы.
Текущее решение использует частичную явную специализацию в классах, полученных пользователем для определения различных реализаций метода getOutput
. Хотя решения действительно работают, это слишком сложно. Я хотел бы упростить его и буду признателен за любые идеи о том, как это можно сделать, не теряя функциональности текущего дизайна.
EDIT: Меня беспокоит простота реализации метода getOutput
с точки зрения пользователя. Меня не волнует, насколько сложна реализация базовых классов.
Пример реализации производного класса:
class PipeOutputClass: public AlgorithmOutput<PipeOutputClass>
{
public:
template <size_t N>
auto getOutput(size_t c_Idx) const
{
return getOutputImpl<N>::apply(this, c_Idx);
}
template<size_t N, typename S> friend struct getOutputImpl;
template<size_t N, typename = void>
struct getOutputImpl
{
static auto apply(
PipeOutputClass const* p_Self,
size_t c_Idx
)
{
throw std::runtime_error("Wrong template argument.");
}
};
template <typename S>
struct getOutputImpl<0, S>
{
static std::unique_ptr<double> apply(
PipeOutputClass const* p_Self,
size_t c_Idx
)
{
std::unique_ptr<double> mydouble(new double(10));
return mydouble;
}
};
template <typename S>
struct getOutputImpl<1, S>
{
static std::unique_ptr<int> apply(
PipeOutputClass const* p_Self,
size_t c_Idx
)
{
std::unique_ptr<int> myint(new int(3));
return myint;
}
};
};
Что такое параметр шаблона 'S'? – TartanLlama
Как определяется «N»? – Jarod42
@ Jarod42 Если я правильно понял ваш вопрос, нужный 'N' определяется пользователем' getOutputImpl' пользователем (т. Е. Разработчиком класса). Однако есть лучшее решение - см. Принятый ответ. Это может также лучше объяснить то, что я пытался сделать. – user1391279