Расширение типа в С++
К сожалению, UFCS не попал в С++ 17, и это оставило меня с повторяющейся проблемой:
Иногда я хочу предоставить дополнительные возможности типов, используя синтаксис вызова метода (без написания глобальных функций). Это особенно удобно при работе с монадами.
Я вижу два варианта: одно - наследование, а другое - инкапсуляция. Поскольку вы не можете безопасно наследовать от контейнеров STL, это оставляет инкапсуляцию. Например, я хочу расширить std::optional
, поэтому пишу:
template <typename T>
struct myoption {
// Some functionality
private:
std::optional<T> impl;
};
Моя проблема в том, что каждый раз, когда я хочу это сделать, я в основном должен писать все конструкторы (и необходимые методы, которые вы можете использовать с исходным типом, например push_back
для векторов), который имеет исходный тип. Даже более простой контейнер, как и факультативный, имеет 9 конструкторов. При использовании наследования я могу просто "наследовать" методы и конструкторы суперкласса. Есть ли способ сделать это проще с помощью инкапсуляции?
Ответы
Ответ 1
Я бы реализовал его, используя личное наследование:
#define MAKE_PUBLIC(method) using std::vector<T>::method
template <typename T>
struct My_vector : private std::vector<T> {
MAKE_PUBLIC(push_back);
MAKE_PUBLIC(pop_back);
};
int main() {
My_vector<int> v;
v.push_back(3);
std::vector<int>* vec = new My_vector<int>; // won't compile
}
Таким образом, вы можете не создавать объекты с типом dynamic My_vector
и уменьшать усилия, чтобы сделать унаследованные методы доступными простым макросом (или с помощью директивы) вместо создания вперед функции для каждой функции-члена и перегрузки.