Бьярне ошибается в этом примере ADL или у меня ошибка компилятора?

я читаю Язык программирования C ++, 4-е издание (от Бьярне Страуструп) около . Вот цитата (26.3.6, Сверхагрессивная ADL):

Зависимый от аргумента поиск (часто называемый ADL) очень полезен, чтобы избежать многословия (14.2.4). Например:

#include <iostream>

int main()
{
std::cout << "Hello, world" << endl; // OK because of ADL
}

Без аргументно-зависимого поиска endl Манипулятор не будет найден. Как таковой, компилятор замечает, что первый аргумент << является ostream определяется в std, Поэтому он ищет endl в std и находит его (в <iostream>).

И вот результат производится компилятором (режим C ++ 11):

prog.cpp: In function ‘int main()’:
prog.cpp:4:36: error: ‘endl’ was not declared in this scope
std::cout << "Hello, world" << endl;
^

Либо это ошибка в компиляторе, либо в книге. Что говорит стандарт?

Обновить:

Мне нужно немного уточнить. Я знаю, что правильный ответ заключается в использовании std::endl, Вопрос был о тексте в книге. Как Лахлан Истон уже сказал, это не просто опечатка. Весь абзац (вероятно) неверен. Я могу принять такую ​​ошибку, если книга написана другим (менее известным) автором, но у меня были (и остаются) сомнения, потому что она была написана Бьярне.

80

Решение

Это не ошибка в компиляторе. ADL используется для поиска функции не аргументы. operator<< эта функция найдена через ADL, посмотрев на параметры std::cout и (что должно быть) std::endl,

83

Другие решения

Для тех, кто говорит, что это опечатка, это не так. Либо Бьярне допустил ошибку, либо компилятор ошибся.
Абзац после того, что опубликовано ОП гласит

Без аргументно-зависимого поиска манипулятор endl не был бы
найденный. Как таковой, компилятор замечает, что первый аргумент << является
ostream, определенный в std. Следовательно, он ищет endl в std и
находит его (в<iostream>).

48

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

std::operator<<(std::cout, "Hello, world").operator<<(std::endl);

без ADL. Это то, что Бьярне имел в виду под многословием.


Я стою исправлено. Как Лахлан Истон указывает, что это не опечатка, а ошибка в книге. У меня нет доступа к этой книге, поэтому я не мог прочитать этот абзац и сам понять его. Я сообщил об этой ошибке Бьярне, чтобы он мог ее исправить.


Смешной. Тот же пример в Википедии а также

Обратите внимание, что std::endl это функция, но она требует полной квалификации,
так как он используется в качестве аргумента operator<< (std::endl это функция
указатель, а не вызов функции).

Без сомнения, это ошибка в книге. Тем не менее пример std::operator<<(std::cout, "Hello, world").operator<<(std::endl); показывает, как ADL помогает уменьшить многословие.


Благодаря gx_ за указывая на мою ошибку.

20

Подсказка в названии «поиск, зависящий от аргумента».

Это поиск для неквалифицированных имен функций, который работает в зависимости на аргументы.

Это не имеет ничего общего с поиском за аргументы.

Бьярне оговорилась.

10

У меня нет книги, но, похоже, это ошибка в книге, тот факт, что в ней отсутствует классификатор пространства имен, не имеет ничего общего с ADL. Так должно быть std::endl,

8

Да, это ошибка — пример некорректен и не должен компилироваться. ADL применяется к неквалифицированным именам функций, которые вводят выражения вызова функций. endl это id-выражение, пытающееся найти std::endl, endl не вводит выражение вызова функции, поэтому поиск по аргументам для него не используется, используется только неквалифицированный поиск, поэтому он не найдет std::endl как предполагалось.

Более простой и правильный пример:

#include <vector>

int main()
{
std::vector<int> x, y;
swap(x,y); // calls std::swap due to ADL
}

Таким образом, перед вызовом функции (например, f(x,y,z)) с неквалифицированным идентификатором (например, f), сначала ищутся параметры функции (например, x,y,z) анализируются для определения их типа. Список связанных пространств имен формируется на основе типов (например, включающее пространство имен определения типа является связанным пространством имен). Эти пространства имен затем дополнительно ищутся для функции.

Целью примера Бьярне является показать ADL std::operator<< функция, а не std::endl, Это требует дополнительного понимания того, что перегруженные операторы на самом деле являются выражениями вызова функций, поэтому x << y средства operator<<(x,y), а также operator<< является неквалифицированным именем, и поэтому к нему применяется ADL. Тип LHS является std::ostream так std является связанным пространством имен, и, следовательно, std::operator<<(ostream&, ...) найден.

Исправленный комментарий должен гласить:

Без аргументно-зависимого поиска перегруженный << оператор в std пространство имен не будет найдено. Как таковой, компилятор замечает, что первый аргумент << Ostream определен в стандарте Поэтому он ищет оператора << в STD и находит его (в <iostream>).

4
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector