Копирование std::tuple

Я пытался присвоить некоторые значения классу, производному от std::tuple. Первое, о чем я подумал, это использовать make_tuple, а затем скопировать его с помощью operator=, но это не сработало.

Если бы вместо этого я вручную назначал отдельные значения кортежа, проблем не было бы.

Итак, я написал небольшой фрагмент кода, извлекая его из проекта, чтобы протестировать конкретно эту единственную вещь:

#include <tuple>
template <class idtype>
class Userdata: public std::tuple<idtype, WideString, int>
{
  public:
  /* compile error
  void assign1(const idtype& id, const WideString& name, const int lvl)
  {
    (*this)=std::make_tuple(id, name, lvl);
  }
  */
  void assign2(const idtype& id, const WideString& name, const int lvl)
  {
    (std::tuple<idtype, WideString, int>)(*this)=std::make_tuple(id, name,  lvl);
  }
  void assign3(const idtype& id, const WideString& name, const int lvl)
  {
    std::get<0>(*this)=id;
    std::get<1>(*this)=name;
    std::get<2>(*this)=lvl;
  }
  void print(const WideString& testname) const
  {
    std::cout << testname << ": " << std::get<0>(*this) << " " << std::get<1>(*this) << " " << std::get<2>(*this) << std::endl;
  }

  Userdata()
  {
  }

};


int main(int argc, char *argv[])
{
  Userdata<int> test;
  /*
  test.assign1("assign1", 1, "test1", 1);
  test.print();
  */
  test.assign2(2, "test2", 2);
  test.print("assign2");
  test.assign3(3, "test3", 3);
  test.print("assign3");
}

Результаты

assign2: 0  0 
assign3: 3 test3 3

Только assign3 дает ожидаемый результат. Итак, хотя я могу легко использовать функцию assign3, мне все еще интересно, что не так с assign2.


person DrHell    schedule 16.08.2017    source источник
comment
Кстати, вы уверены, что хотите здесь наследование, а не простую композицию?   -  person Baum mit Augen    schedule 16.08.2017
comment
@BaummitAugen Я собирался предложить то же самое, но подумал, что, может быть, я чего-то не понимаю.   -  person Retired Ninja    schedule 16.08.2017
comment
@BaummitAugen Спасибо за ответ ниже. Да, я хотел наследование, потому что другие функции ожидают взаимодействия с кортежем, поэтому это казалось самым простым путем. :)   -  person DrHell    schedule 16.08.2017


Ответы (1)


(std::tuple<idtype, WideString, int>)(*this)

создает новый временный объект, который вы затем назначаете. Вместо этого приведите к ссылке:

(std::tuple<idtype, WideString, int>&)(*this)=std::make_tuple(id, name,  lvl);
person Baum mit Augen    schedule 16.08.2017