c ++ конструктор копирования (ссылки) и конструктор перемещения класса сожительства

Вот код, показывающий намерение:

template<typename T>
class B 
{
  public:
  // this should indeed set t_ as a reference to t
  B(T& t):t_(t){}
  // this should instead set t_ as a copy of t
  B(T&& t):t_(t){}
  T& t_; // maybe type should be something else ?
};

A a;
B b1(a); // fine
B b2(A()); // problem

Было бы возможно ?


person Vince    schedule 06.03.2020    source источник
comment
У вас не может быть одновременно копии и ссылки. Вам нужно выбрать одно или другое.   -  person NathanOliver    schedule 06.03.2020
comment
Хотите что-то вроде того?   -  person Jarod42    schedule 06.03.2020
comment
Вы хотите, чтобы и b1, и b2 были одного типа или нет?   -  person HolyBlackCat    schedule 07.03.2020
comment
Кстати, B b2(A()); досадный разбор, должно быть B b2{A()}.   -  person Jarod42    schedule 07.03.2020
comment
@ Jarod42 все еще нужно осмыслить, но мне кажется, что я хочу этого. Почему бы не предложить в качестве ответа?   -  person Vince    schedule 07.03.2020


Ответы (2)


В C ++ 17 с помощью дедукции аргументов шаблона класса (CTAD) вы может сделать:

template<typename T>
class B 
{
public:
  B(T&& t):t_(t){}
  T t_;
};

template <typename T> B(T&) -> B<T&>;
template <typename T> B(T&&) -> B<T>;

Демо

person Jarod42    schedule 06.03.2020

Я предполагаю, что вы хотите, чтобы и b1, и b2 имели один и тот же тип, B<A>.

Если это так, вы можете ab использовать std::shared_ptr:

std::shared_ptr<T> ptr;

B(T &src) : ptr(std::shared_ptr<T>(), &src) {}
B(T &&src) : ptr(std::make_shared<T>(srd::move(src))) {}

Если вам не нравится это решение, вы можете сделать что-то вроде этого:

std::optional<T> storage;
T &ref;

B(T &src) : ref(src) {}
B(T &&src) : storage(std::move(src)), ref(*storage) {}

Обратите внимание, что в этом случае вам нужны настраиваемые конструкторы копирования / перемещения, иначе ваш класс не будет соответствовать правило трех.

Вы также можете использовать здесь std::unique_ptr вместо std::optional.

person HolyBlackCat    schedule 06.03.2020