методы расширения — расширение типа в переполнении стека

К сожалению, UFCS не попал в C ++ 17, и это оставило меня с повторяющейся проблемой:
Иногда я хочу дать типам дополнительную функциональность, используя синтаксис вызова метода (без написания глобальных функций). Это особенно пригодится при работе с монадами.

Я вижу два варианта: один — наследование, а другой — инкапсуляция. Поскольку вы не можете безопасно наследовать от контейнеров STL, это оставляет инкапсуляцию. Например, я хочу продлить std::optionalтак я и пишу:

template <typename T>
struct myoption {
// Some functionality
private:
std::optional<T> impl;
};

Моя проблема в том, что каждый раз, когда я хочу сделать это, мне нужно написать все конструкторы (и необходимые методы, которые вы можете использовать с исходным типом, например, push_back для векторов) оригинальный тип имеет. Даже в более простом контейнере, например, в дополнительном, есть 9 конструкторов. Используя наследование, я могу просто «наследовать» методы и конструкторы суперкласса. Есть ли способ сделать это проще с помощью инкапсуляции?

10

Решение

Я бы реализовал это с помощью частного наследования:

#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
}

Таким образом, вы можете убедиться, что не можете создавать объекты с динамический тип My_vector и уменьшите усилия, чтобы сделать наследуемые методы доступными с помощью простого макроса (или с помощью директивы) вместо создания прямых функций для каждой функции-члена и перегрузки.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]