Информация об изменениях

Сообщение Re[2]: Про красивость работы с std::vector от 16.03.2025 10:25

Изменено 16.03.2025 10:44 rg45

Re[2]: Про красивость работы с std::vector
Здравствуйте, sergii.p, Вы писали:

SP>то, что vector (и не только он) скрытно может копировать данные — это действительно проблема всей stl. Я бы решал её переопределением своего "пуританского" вектора (без блекджека).


SP>
SP>template <typename T>
SP>class greedy_vector : public std::vector<T> {
SP>public:
SP>    using std::vector<T>::vector;

SP>    greedy_vector explicit_copy() const {
SP>        return *this;
SP>    }

SP>private:
SP>    greedy_vector(const greedy_vector& other): std::vector<T>(other) {}
SP>};
SP>


SP>теперь просто так не скопируешь:


SP>
SP>greedy_vector<int> data{100};
SP>const auto copy = data; // ошибка
SP>


Я бы это задизайнил так:

http://coliru.stacked-crooked.com/a/68033678ff7f1a67

#include <vector>

template <typename T>
class greedy_vector : public std::vector<T> {
public:
    using std::vector<T>::vector;

    friend greedy_vector explicit_copy(const greedy_vector& orig) {
        return greedy_vector(orig); // enforced RVO
    }

private:
    greedy_vector(const greedy_vector&) = default;
};

int main()
{
    greedy_vector<int> data{100};
    const auto copy = explicit_copy(data);
}


Благодаря guaranteed copy elision, такая реализация explicit_copy равнозначна конструктору, с практической точки зрения. И для конструктора копирования здесь вполне подойдет вариант, сгенерированный компилятором.
Re[2]: Про красивость работы с std::vector
Здравствуйте, sergii.p, Вы писали:

SP>то, что vector (и не только он) скрытно может копировать данные — это действительно проблема всей stl. Я бы решал её переопределением своего "пуританского" вектора (без блекджека).


SP>
SP>template <typename T>
SP>class greedy_vector : public std::vector<T> {
SP>public:
SP>    using std::vector<T>::vector;

SP>    greedy_vector explicit_copy() const {
SP>        return *this;
SP>    }

SP>private:
SP>    greedy_vector(const greedy_vector& other): std::vector<T>(other) {}
SP>};
SP>


SP>теперь просто так не скопируешь:


SP>
SP>greedy_vector<int> data{100};
SP>const auto copy = data; // ошибка
SP>


Я бы это задизайнил так:

http://coliru.stacked-crooked.com/a/68033678ff7f1a67

#include <vector>

template <typename T>
class greedy_vector : public std::vector<T> {
public:
    using std::vector<T>::vector;

    friend greedy_vector explicit_copy(const greedy_vector& orig) {
        return greedy_vector(orig); // guaranteed RVO
    }

private:
    greedy_vector(const greedy_vector&) = default;
};

int main()
{
    greedy_vector<int> data{100};
    const auto copy = explicit_copy(data);
}


Благодаря guaranteed copy elision, такая реализация explicit_copy равнозначна конструктору, с практической точки зрения. И для конструктора копирования здесь вполне подойдет вариант, сгенерированный компилятором.