이 ADL 예제에 대해 Bjarne이 틀렸습니까? 아니면 컴파일러 버그가 있습니까?
인수 종속 조회에 대한 The C ++ Programming Language, 4th Edition (by Bjarne Stroustrup )을 읽고 있습니다. 다음은 인용문입니다 (26.3.6, Overaggressive ADL) :
인수 종속 조회 (종종 ADL이라고 함)는 자세한 정보를 피하는 데 매우 유용합니다 (14.2.4). 예를 들면 :
#include <iostream> int main() { std::cout << "Hello, world" << endl; // OK because of ADL }
인수 종속 조회가 없으면
endl
조작자를 찾을 수 없습니다. 그 첫 번째 인수는 것을 컴파일러 공지이므로<<
된다ostream
정의std
. 따라서endl
instd
을 찾아서 찾습니다 (in<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
. 질문은 책의 텍스트에 관한 것이 었습니다. 로 클런 이스턴은 이미 그냥 오타 아니다 말했다. 전체 단락이 (아마도) 잘못되었습니다. 이 책이 다른 (덜 알려진) 저자의 책이라면 이런 종류의 오류를 받아 들일 수 있지만, Bjarne이 저술했기 때문에 나는 여전히 의심 스럽습니다.
컴파일러의 버그가 아닙니다. ADL은 인수가 아닌 함수 를 조회하는 데 사용됩니다 . 여기에서 ADL을 통해 매개 변수 와 (무엇이되어야하는지) 살펴보면서 찾은 함수 입니다.operator<<
std::cout
std::endl
오타라고 말하는 사람들에게는 그렇지 않습니다. Bjarne이 실수를했거나 컴파일러가 잘못했습니다. OP가 게시 한 다음 단락은 다음과 같습니다.
인수 종속 조회가 없으면 endl 조작자를 찾을 수 없습니다. 그대로 컴파일러는 <<에 대한 첫 번째 인수가 std에 정의 된 ostream임을 알아 차립니다. 따라서 std에서 endl을 찾고 (에서
<iostream>
) 찾습니다 .
다른 사람들이 이미 지적했듯이 책의 오타입니다. 그러나 책에서 의미하는 것은
우리가
std::operator<<(std::cout, "Hello, world").operator<<(std::endl);
ADL없이. 그것이 Bjarne이 장황함을 의미하는 것입니다.
나는 바로 잡았다. 로 클런 이스턴는 지적이 오타하지만 아닌 실수 책이다. 나는이 책에 접근 할 수 없어서 그 문단을 읽고 스스로 깨닫지 못한 것입니다. 나는이 실수를 Bjarne에게보고하여 그가 고칠 수 있도록했습니다.
이상한. 동일한 예가 Wikipedia에 있으며
참고이
std::endl
기능이지만,이에 대한 인수로 사용되기 때문에 그것은, 전체 자격을 필요로operator<<
(std::endl
함수 포인터가 아닌 함수 호출).
의심 할 여지없이 책의 실수입니다. 그럼에도 불구하고이 예제 std::operator<<(std::cout, "Hello, world").operator<<(std::endl);
는 ADL이 자세한 정도를 줄이는 데 어떻게 도움이되는지 보여줍니다.
힌트는 "인수 종속 조회"라는 이름에 있습니다.
이 작품 것으로, 규정되지 않은 함수 이름에 대한 조회의 따라 온 인수 .
그것은 조회와는 아무 상관 없어 있어요 에 대한 인수를.
비얀 미스 포크.
책은 없지만 이것은 책의 오류 인 것 같습니다. 네임 스페이스 한정자가 없다는 사실은 ADL과 관련이 없습니다. 이어야합니다 std::endl
.
예, 오류입니다. 예제의 형식이 잘못되어 컴파일해서는 안됩니다. 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
}
In summary, before a function call (eg f(x,y,z)
) with an unqualified id (eg f
) is looked up, first the parameters of the function (eg x,y,z
) are analyzed to determine their type. A list of associated namespaces is formed based on the types (for example the enclosing namespace of the type's definition is an associated namespace). These namespaces are then additionally searched for the function.
The intention of Bjarne's example is to show off the ADL of the std::operator<<
function, and not std::endl
. This requires an additional understanding that overloaded operators are in fact function call expressions, so x << y
means operator<<(x,y)
, and operator<<
is an unqualified name, and therefore ADL applies to it. The type of the LHS is std::ostream
so std
is an associated namespace, and therefore std::operator<<(ostream&, ...)
is found.
The corrected comentary should read:
Without argument-dependent lookup, the overloaded
<<
operator in thestd
namespace would not be found. As it is, the compiler notices that the first argument to << is an ostream defined in std. Therefore, it looks for the operator<<
in std and finds it (in<iostream>
).
'code' 카테고리의 다른 글
ASP.Net의 dll.refresh 파일은 무엇입니까? (0) | 2020.10.08 |
---|---|
클래스 내부 또는 외부의 함수 선언 (0) | 2020.10.08 |
gulp 이벤트에서 console.log를 stdout으로 (0) | 2020.10.07 |
CloudFormation은 내 DynamoDB 생성 JSON이 유효하지 않다고 주장하지만 .. 방법을 볼 수 없습니다. (0) | 2020.10.07 |
wpf에서 창 내 요소의 절대 위치 가져 오기 (0) | 2020.10.07 |