Katakanlah, saya punya kelas:

class Person {
    std::string name;
    int age;
    int height;
    int weight;
    int wage;
};

Dan tabel yang diisi dengan banyak Person.

Saya ingin mengambil "kolom" ke-3, ke-4 untuk membuat tabel baru. Artinya, jika kita memiliki sesuatu seperti:

{"Obama", 60, 178, 72, 3000},
{"Trump", 70, 185, 120, 4000},
{"Biden", 80, 180, 90, 5000},

Maka saya ingin mengambil tabel seperti:

{178, 72},
{185, 120},
{180, 90}

Contoh di atas hanyalah contoh, saya tidak dapat membuat instance yang baru dibuat. Beberapa variabel anggota kelas mahal untuk disalin, jadi saya ingin memiliki tabel referensi yang tidak memiliki.

Apakah ada cara untuk membuat API seperti extract({3, 4}) di C++?

0
frozenca 19 November 2020, 13:15

1 menjawab

Jawaban Terbaik

Berikut adalah sesuatu yang saya buat bersama. Bagian inti adalah tipe Value, berdasarkan std::variant. Pencetakan nilai dilakukan melalui std::visit.

using Value = std::variant<int, std::reference_wrapper<const std::string>>;
struct ValuePrinter {
    std::ostream* os;
    void operator()(int v) { *os << v; }
    void operator()(std::reference_wrapper<const std::string> v) { *os << v.get(); }
};

std::ostream& operator<<(std::ostream& os, const Value& v) {
    std::visit(ValuePrinter{&os},v);
    return os;
}

Fungsi extract sederhana, maka:

Value getter(const Person& p, int i) {
  if (i == 0) return p.name;
  if (i == 1) return p.age;
  if (i == 2) return p.height;
  if (i == 3) return p.weight;
  if (i == 4) return p.wage;
  throw -1;
}

std::vector<Value> extract(const Person& p, std::vector<int> indices) {
  std::vector<Value> ret;
  for (int idx : indices)
     ret.emplace_back(getter(p, idx));

  return ret;
}
1
Botje 19 November 2020, 12:15