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

Сообщение Re: cref<> in<> от 04.02.2023 14:42

Изменено 04.02.2023 14:45 Sm0ke

Re: cref<> in<>
Я долго откладывал написание соображений на эту тему. В начале думал создать отдельный пост.
Предлагаю рассмотреть мою тестовую версию двух вспомогательных шаблонных классов cref<T> и in<T> чтобы найти подходящее решение.

https://cpp.godbolt.org/z/ETjzoKhKj

cref<T> это простой алиас на const T &

in<T> мувает полученный параметр во внутреннее состояние с предоставлением доступа на запись/чтение.
Его нестатический метод move() нужен к примеру чтобы вернуть значение из функции.

Про inout<> и ref<> я напишу отдельно (скорее всего ответом на исходную тему).
std::array мувать смысла видимо нет, вот для него и ref<> сойдёт.

#include <utility>
#include <vector>
#include <iostream>

template <typename T>
using cref = const T &;

template <typename T>
struct in {
  using t_data = T;
  using t_read = const T &;
  using t_write = T &;
  using t_move = T &&;

  // data
  t_data    m_value;

  in(t_data && p) : m_value{std::move(p)} {}
  in(t_data & p) : m_value{std::move(p)} {}

  t_read read() const { return m_value; }
  t_write write() { return m_value; }
  t_move move() { return std::move(m_value); }

  // forbid
  in() = delete;
  in(cref<in>) = delete;
  in(in &&) = delete;
  in & operator = (cref<in>) = delete;
  in & operator = (in &&) = delete;
};

// testing

using t_vector = std::vector<int>;

void print(cref<t_vector> p, char name) {
  std::cout << name << ": ";
  if( p.empty() ) { std::cout << "empty vector\n"; }
  else {
    for( typename t_vector::const_reference it : p ) {
      std::cout << it << ' ';
    }
    std::cout << '\n';
  }
}

void test_in(in<t_vector> p) {
  std::cout << "test_in()\n";
  p.write().push_back(4);
  print(p.write(), 'p');
  std::cout << "test_in() end\n";
}

t_vector test_in_ret(in<t_vector> p) {
  std::cout << "test_in_ret()\n";
  return p.move();
}

int main() {
  std::cout << "# test 1\n";
  {
    t_vector v{1, 2, 3};
    print(v, 'v');
    test_in(v);
    print(v, 'v');
  }
  std::cout << "# test 2\n";
  {
    t_vector d{4, 5}, v;
    print(d, 'd'); print(v, 'v');
    v = test_in_ret(d);
    print(d, 'd'); print(v, 'v');
  }
  return 0;
}
Re: cref<> in<>
Я долго откладывал написание соображений на эту тему. В начале думал создать отдельный пост.
Предлагаю рассмотреть мою тестовую версию двух вспомогательных шаблонных классов cref<T> и in<T> чтобы найти подходящее решение.
Как на ваш взгляд можно сделать лучше?

https://cpp.godbolt.org/z/ETjzoKhKj

cref<T> это простой алиас на const T &

in<T> мувает полученный параметр во внутреннее состояние с предоставлением доступа на запись/чтение.
Его нестатический метод move() нужен к примеру чтобы вернуть значение из функции.

Про inout<> и ref<> я напишу отдельно (скорее всего ответом на исходную тему).
std::array мувать смысла видимо нет, вот для него и ref<> сойдёт.

#include <utility>
#include <vector>
#include <iostream>

template <typename T>
using cref = const T &;

template <typename T>
struct in {
  using t_data = T;
  using t_read = const T &;
  using t_write = T &;
  using t_move = T &&;

  // data
  t_data    m_value;

  in(t_data && p) : m_value{std::move(p)} {}
  in(t_data & p) : m_value{std::move(p)} {}

  t_read read() const { return m_value; }
  t_write write() { return m_value; }
  t_move move() { return std::move(m_value); }

  // forbid
  in() = delete;
  in(cref<in>) = delete;
  in(in &&) = delete;
  in & operator = (cref<in>) = delete;
  in & operator = (in &&) = delete;
};

// testing

using t_vector = std::vector<int>;

void print(cref<t_vector> p, char name) {
  std::cout << name << ": ";
  if( p.empty() ) { std::cout << "empty vector\n"; }
  else {
    for( typename t_vector::const_reference it : p ) {
      std::cout << it << ' ';
    }
    std::cout << '\n';
  }
}

void test_in(in<t_vector> p) {
  std::cout << "test_in()\n";
  p.write().push_back(4);
  print(p.write(), 'p');
  std::cout << "test_in() end\n";
}

t_vector test_in_ret(in<t_vector> p) {
  std::cout << "test_in_ret()\n";
  return p.move();
}

int main() {
  std::cout << "# test 1\n";
  {
    t_vector v{1, 2, 3};
    print(v, 'v');
    test_in(v);
    print(v, 'v');
  }
  std::cout << "# test 2\n";
  {
    t_vector d{4, 5}, v;
    print(d, 'd'); print(v, 'v');
    v = test_in_ret(d);
    print(d, 'd'); print(v, 'v');
  }
  return 0;
}