Неклассовые значения всегда имеют cv-неквалифицированные типы

В разделе 9.10 раздела 9 говорится, что "неклассические значения всегда имеют cv-неквалифицированные типы". Это заставило меня задуматься...

int foo()
{
    return 5;
}

const int bar()
{
    return 5;
}

void pass_int(int&& i)
{
    std::cout << "rvalue\n";
}

void pass_int(const int&& i)
{
    std::cout << "const rvalue\n";
}

int main()
{
    pass_int(foo()); // prints "rvalue"
    pass_int(bar()); // prints "const rvalue"
}

В соответствии со стандартом, нет такой вещи, как константа rvalue для неклассических типов, но bar() предпочитает привязываться к const int&&. Является ли это ошибкой компилятора?

EDIT: По-видимому, this также является константой:)

EDIT: эта проблема, похоже, исправлена ​​в g++ 4.5.0, обе строки печатают "rvalue" сейчас.

Ответ 1

Комитет уже, похоже, осознает, что в этой части стандарта есть проблема. CWG issue 690 рассказывает о некоторой схожей проблеме с точно такой же частью стандарта (в "дополнительной заметке" от сентября 2009 года). Я предполагаю, что новый язык будет подготовлен для этой части стандарта в ближайшее время.

Изменить: я только что отправил сообщение на comp.std.С++, отметив проблему и предложив новую формулировку для соответствующей части стандарта. К сожалению, будучи модерируемой новостной группой, почти все, вероятно, забудут этот вопрос к тому моменту, когда он сделает это через очередь утверждения там.

Ответ 2

Хорошая точка. Я думаю, есть две вещи, на которые нужно обратить внимание: 1) как вы указали неклассическое значение rvalue и 2) как работает разрешение перегрузки:

Критерии отбора для лучших функция - количество аргументов, насколько аргументы соответствуют list-type-list кандидата функция, [...]

Я не видел ничего в стандарте, который говорит мне, что неклассовые значения r обрабатываются специально во время разрешения перегрузки.

Ваш вопрос рассмотрен в проекте стандарта, который у меня есть (N-4411):

Однако вступление в игру - это параллельное чтение ссылочного связывания, неявных последовательностей преобразования, ссылок и разрешения перегрузки в целом:

13.3.3.1.4 Связывание ссылок

2 Когда параметр ссылочного типа не связано непосредственно с аргументом выражение, последовательность преобразования     это тот, который требуется для преобразования выражения аргумента в базовый тип ссылки согласно     до 13.3.3.1.

и

13.3.3.2 Ранжирование неявных последовательностей преобразования

3 Две неявные последовательности преобразования одна и та же форма неразличима последовательности преобразований, если один из применяются следующие правила:

- Стандартная последовательность преобразования S1 является лучшей последовательностью преобразования, чем стандарт
       последовательность преобразования S2, если

- S1 и S2 являются ссылочными привязками (8.5.3), и ни одна из них не относится к неявный параметр объекта нестатический     функция-член, объявленная без ref-квалификатора, и либо S1 связывает Ссылка на lvalue     к lvalue и S2 связывает ссылку rvalue или S1 связывает значение rvalue ссылка на rvalue и S2     связывает ссылку lvalue.

[Пример:

int i;
int f();
int g(const int&);
int g(const int&&);
int j = g(i); // calls g(const int&)
int k = g(f()); // calls g(const int&&)