[vc10, rvalue references] Поломали, однако
От: byleas  
Дата: 20.10.09 20:43
Оценка:
Сабж.

Такой код уже не катит:
  // <utility>
  template <class T>
  struct identity
  {
    typedef T type;
    const T& operator()(const T& x) const { return x; }
  };

  template <class T>
  inline
  T&& forward(typename identity<T>::type&& t)
  {
    return t;
  }


struct X{};

void g(X&& gx);
void f(X&& fx)
{
  g(fx); // can't convert from 'X' to 'X&&' (You cannot bind an lvalue to an rvalue reference) (1)
  g(std::forward<X>(fx); // аналогично. нонсенс! (2)

  X x;
  X&& rvx1 = x;   // error (3)
  X&& rvx2 = X(); // ok (4)
}


Вроде бы с++0х были какие-то предложения по изменениям, но в основном это было связано с работой perfect forwarding. А вот чтоб так брутально..
gcc 4.5 считает, что здесь всё ок. Скорее всего (точно не помню сейчас), в первом вызове "g(fx)" фактически получим lvalue reference параметром. Но почему это стало ошибкой?

Примеры из блога vc10 также поломались.

Вообще, с forward<> понятно, ситуация описана в N2951, где сравниваются 6 (!) реализаций. Последняя самая зубодробительная, приведена ниже.
Неясен лишь запрет неявного преобразования lvalue в rvalue (3).

// предложенная реализация forward<>
  template <class T, class U>
  inline T&& forward(U&& u, 
                            typename enable_if<
                              (is_lvalue_reference<T>::value ? is_lvalue_reference<U>::value : true) &&
                               is_convertible<typename remove_reference<U>::type*, typename remove_reference<T>::type*>::value,
                                          void>::type* =0)
  {
    return static_cast<T&&>(u);
  }
c++0x
Re: [vc10, rvalue references] Поломали, однако
От: gear nuke  
Дата: 21.10.09 20:36
Оценка: 6 (1) +1 :)
Здравствуйте, byleas, Вы писали:

B>
B>  X x;
B>  X&& rvx1 = x;   // error (3)


B>Неясен лишь запрет неявного преобразования lvalue в rvalue (3).


Наверное, что бы нельзя было разрушить объект x.
vector<X> vx;
vx.push_back(rvx1); // move
vx.push_back(x);    // nothing to copy


Вообще, A Safety Problem with RValue References заставила меня прийти к выводу, что убийца C++ давно уже есть, называется он C++0x. Послений, разрушив предшественника, так и не будет реализован ... и дело даже не в концептах
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[2]: [vc10, rvalue references] Поломали, однако
От: SleepyDrago Украина  
Дата: 22.10.09 13:10
Оценка:
Здравствуйте, gear nuke, Вы писали:
GN>Здравствуйте, byleas, Вы писали:
B>>
B>>  X x;
B>>  X&& rvx1 = x;   // error (3)
GN>


B>>Неясен лишь запрет неявного преобразования lvalue в rvalue (3).


GN>Наверное, что бы нельзя было разрушить объект x.

GN>
GN>vector<X> vx;
GN>vx.push_back(rvx1); // move
GN>vx.push_back(x);    // nothing to copy
GN>


GN>Вообще, A Safety Problem with RValue References ...


интересно услышать мнение на тему "какой вариант контейнер + movable станет стандартом де факто ?"
или так и продолжим заниматься swaptimization
Re[3]: [vc10, rvalue references] Поломали, однако
От: byleas  
Дата: 22.10.09 18:23
Оценка:
Здравствуйте, SleepyDrago, Вы писали:

SD>интересно услышать мнение на тему "какой вариант контейнер + movable станет стандартом де факто ?"

SD>или так и продолжим заниматься swaptimization
То есть?
Re: [vc10, rvalue references] Поломали, однако
От: alexeiz  
Дата: 27.10.09 07:45
Оценка:
В <utility> forward теперь реализовывается как:
template<class _Ty> inline
    _Ty&& forward(typename identity<_Ty>::type& _Arg)
    {    // forward _Arg, given explicitly specified type parameter
    return ((_Ty&&)_Arg);
    }


Я посмотрел, он проходит 4 из 5 тестов. Не проходит только C: should not forward an rvalue as an lvalue. Но это не так страшно, как кажется на первый взгляд. В тесте происходит binding of "A const" rvalue to "A const &" lvalue. А это и в C++03 работает.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.