Что такое ссылка rvalue на тип функции?

Недавно я задумался о концепциях С++ 0x для glvalues, xvalues ​​и prvalues, а также для ссылок rvalue. Однако есть одна вещь, которая еще ускользает от меня:

Что такое "ссылка rvalue на тип функции? Это буквально многократно упоминается в черновиках. Почему была введена такая концепция? Каковы его использование?

Ответы

Ответ 1

Я ненавижу быть круговым, но ссылка rvalue на тип функции - это ссылка rvalue на тип функции. Существует такая функция, как тип функции, например. void (). И вы можете сформировать ссылку rvalue.

В терминах системы классификации, введенной N3055, это значение x.

Его использование редки и неясны, но это не бесполезно. Рассмотрим, например:

void f() {}
...
auto x = std::ref(f);

x имеет тип:

std::reference_wrapper<void ()>

И если вы посмотрите на синопсис для reference_wrapper, он включает в себя:

reference_wrapper(T&) noexcept;
reference_wrapper(T&&) = delete; // do not bind to temporary objects

В этом примере T - это тип функции void (). И поэтому второе объявление формирует ссылку rvalue на тип функции с целью гарантировать, что reference_wrapper не может быть сконструирован с аргументом rvalue. Даже если T является константой.

Если это не было законно, чтобы сформировать ссылку на функцию rvalue, тогда эта защита приведет к ошибке времени компиляции, даже если мы не передали конструктору значение rvalue T.

Ответ 2

В старом стандарте С++ запрещено:

int foo();
void bar(int& value);

int main()
{
    bar(foo());
}

потому что возвращаемый тип foo() является rvalue и передается ссылкой на bar().

Это было разрешено, хотя с расширениями Microsoft разрешены на Visual С++, так как (я думаю) 2005 года.

Возможные обходные пути без С++ 0x (или msvc) будут объявлять

void bar(const int& value); 

или используя временную переменную, сохраняя возвращаемое значение foo() и передавая переменную (как ссылку) в bar():

int main()
{
    int temp = foo();
    bar(temp);
}