Почему мой шаблон оператора = (T &&) привязывается только к const &, но не к &&? - PullRequest
3 голосов
/ 25 апреля 2019

При написании перегруженной функции из ссылки на rvalue и ссылки на const может возникнуть дублирование кода, поэтому я иногда использую оба кода с одним и тем же кодом.Как показано здесь:

#include <iostream>
#include <type_traits>

struct A {
  template <typename T>
  A& operator=(T&&) {
    if constexpr (::std::is_rvalue_reference_v<T&&>) {
      ::std::cerr << "operator= move\n";
    } else {
      ::std::cerr << "operator= copy\n";
    }
    return *this;
  };
};

Теперь я понимаю, что это должно реализовывать как A& operator=(T const&), так и A& operator=(T&&).Поэтому, учитывая этот код, теоретически я ожидал бы, что этот вызов:

int main() {
  A a,b;
  a = b;
  a = ::std::move(b);
}

выдаст следующий вывод:

operator= copy
operator= move

Однако, к моему удивлению, вторая строка (!)отсутствует.Как я могу покрыть оба одновременно?


Я компилирую с g ++ 8.3.0 и -std=c++17.

1 Ответ

0 голосов
/ 25 апреля 2019

Учитывая объяснение, указанное 1201ProgramAlarm, интересным вопросом является то, почему он работает для ситуации или . Ответ прост: вы назначили не const объект, поэтому T был выведен как A&T&& также становится A&), что дает строго лучшее совпадение, чем неявный конструктор копирования, который принимает const A&. Для конструктора перемещения или если вы присвоили const A, подписи идентичны, и в этом случае не-шаблоны предпочтительнее .

...