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

§3.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"
}

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

РЕДАКТИРОВАТЬ: Очевидно, this также является постоянным значением:)

РЕДАКТИРОВАТЬ: Эта проблема, кажется, исправлена ​​в g ++ 4.5.0, теперь обе строки выводят «rvalue».

Ответы [ 2 ]

11 голосов
/ 31 января 2010

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

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

2 голосов
/ 31 января 2010

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

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

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

Ваш вопрос описан в проекте стандарта, который у меня есть (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&&)
...