Почему std :: is_rvalue_reference не делает то, что рекламируется? - PullRequest
0 голосов
/ 13 декабря 2018

Например, если у меня

#include <type_traits>

struct OwnershipReceiver
{
  template <typename T,
            class = typename std::enable_if
            <
                !std::is_lvalue_reference<T>::value
            >::type
           >
  void receive_ownership(T&& t)
  {
     // taking file descriptor of t, and clear t
  }
};

скопировано из Как сделать так, чтобы параметр ссылки rvalue шаблона ТОЛЬКО связывался со ссылкой rvalue?

на плакате используется !std::is_lvalue_referenceвместо сразу более очевидного std::is_rvalue_reference.Я подтвердил это в своем собственном коде, где первый работает, а второй нет.

Кто-нибудь может объяснить, почему очевидное не работает?

1 Ответ

0 голосов
/ 13 декабря 2018

Поскольку для ссылка для пересылки , T никогда не будет выводиться как ссылка на значение.Предположим, что передача объекта типа int в OwnershipReceiver, если объект является lvalue, T будет выведена как lvalue-reference, то есть int&;если объект является значением r, T будет выведено как нереференсное, то есть int.Вот почему std::is_rvalue_reference<T>::value не будет работать, потому что это всегда false.

Обратите внимание, что цель кода - убедиться, что тип параметра OwnershipReceiver является ссылкой-значением, это не такозначают, что тип T также является rvalue-ссылкой.

Другими словами, смысл здесь различать lvalue-reference и non-reference, поэтому !std::is_reference<T>::value тоже работает.


Кстати: если вы придерживаетесь std::is_rvalue_reference,вы можете использовать std::is_rvalue_reference<T&&>::value, как вы нашли в комментарии , или использовать его для параметра t, например,

template <typename T>
auto receive_ownership(T&& t) -> typename std::enable_if<std::is_rvalue_reference<decltype(t)>::value>::type      
{
   // taking file descriptor of t, and clear t
}
...