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&)