Сабж.
Такой код уже не катит:
// <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);
}
Здравствуйте, 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
Здравствуйте, 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
Здравствуйте, SleepyDrago, Вы писали:
SD>интересно услышать мнение на тему "какой вариант контейнер + movable станет стандартом де факто ?"
SD>или так и продолжим заниматься swaptimization
То есть?
В <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 работает.