Rvalues в С++ 03
Как вы можете определить, является ли данный параметр rvalue в С++ 03? Я пишу какой-то очень общий код и мне нужно взять ссылку, если это возможно, или создать новый объект в противном случае. Могу ли я перегружать, чтобы принимать по-значение, а также по-ссылке, и возвращать значения rvalue функцию by-value?
Или у меня очень тошнотворное чувство, что именно поэтому ссылки rvalue находятся в С++ 0x?
Edit:
is_rvalue =! (is_reference || is_pointer)?
Ответы
Ответ 1
По-видимому, существует способ определить, является ли выражение rvalue или lvalue в С++ 03 (я говорю, по-видимому, потому, что я не уверен, насколько хорошо я понимаю эту технику). Обратите внимание, что для того, чтобы использовать технику, макросы препроцессора в значительной степени требуются. Эрик Ниблер написал хорошую статью о том, как она работает и как она используется в BOOST_FOREACH:
Обратите внимание, что статья довольно тяжелая (по крайней мере, для меня); как говорит Ниблер:
Нет никаких сомнений в том, что это тайный материал, но мы вознаграждены надежным способом определения rvalue-ness и lvalue-ness любого выражения.
Использование определения rvalue, описанного в artcile, может помочь вам решить хотя бы некоторые из проблем, которые решаются с помощью ссылок на С++ 0x rvalue.
Ответ 2
Как вы можете определить, является ли данный параметр rvalue в С++ 03?
Вы не можете. Все, что вы можете сделать, это доверять вашим клиентам и обманывать:
void call_me_with_anything(const T& const_ref)
{
/* read from const_ref */
}
void call_me_with_rvalue_only_please_i_trust_you(const T& const_ref)
{
T& ref = const_cast<T&>(const_ref);
/* write through ref */
}
Я пишу очень общий код
Тогда я боюсь, что С++ 03 не отрежет вам.
Ответ 3
Или у меня очень тошнотворное чувство, что именно поэтому ссылки rvalue находятся в С++ 0x?
Вы правы, вам нужны ссылки С++ 0x и rvalue для этого.
Ближайшая вещь, о которой я могу думать, - это взять что-то посредством const-reference, поскольку это может связываться с lvalue или rvalue (если rvalue нужно построить временное, это будет). Тем не менее, ваш код не сможет отличить двух.
Ответ 4
Или у меня очень тошнотворное чувство, что именно поэтому ссылки rvalue находятся в С++ 0x?
Угу. Именно поэтому они добавляются в С++ 0x.
Вы не можете создавать перегрузки на С++, чтобы различать значения r и lvalues.
Ответ 5
Я пишу какой-то очень общий код и мне нужно взять ссылку, если это возможно, или создать в противном случае новый объект.
Не будет ли это делать то, что вы хотите?
void f(T& t);
void f(T const& t);
Обратите внимание, что...
T t; f(t); // calls f(T&)
f(T()); // calls f(T const&)