다음 코드에는 함수 이름 충돌이있을 수 없다는 것을 필요로 나타납니다 (놀랍게도?) 중 하나 g++
또는 clang++
로 컴파일되지 않습니다 때문에 BuildStream
에 모호한 호출에 bar::Rectangle
등으로 bar::BuildStream
를 인스턴스화 할 때 입력. 클래스가 네임 스페이스 bar
에 네임 스페이스 foo
에서 수입되는 경우는 네임 스페이스 사이에
#include <iostream>
#include <sstream>
namespace foo {
struct Rectangle { double height, width; };
std::ostream& operator<<(std::ostream& os, const Rectangle& a) { return os; }
inline void BuildStream(std::ostringstream& os) { }
template<typename T, typename... Args>
void BuildStream
(std::ostringstream& os, const T& item, const Args& ...args) {
os << item;
BuildStream(os, args...);
}
} // namespace foo
namespace bar {
inline void BuildStream(std::ostringstream& os) { }
template<typename T, typename... Args>
void BuildStream
(std::ostringstream& os, const T& item, const Args& ...args) {
os << item;
BuildStream(os, args...);
}
using Rectangle = foo::Rectangle;
} // namespace bar
int main(int argc, char* argv[]) {
std::ostringstream os;
bar::BuildStream(os, 1, 2);
bar::BuildStream(os, bar::Rectangle(), bar::Rectangle());
return 0;
}
모호성은 일반적으로 말해서, 그 암시하는 것 같다, 다음 bar
에는 기능이 foo
함수와 동일한 이름이되지 않도록주의해야 케어. 이것은 네임 스페이스의 이점 중 일부에 렌치를 던졌습니다. 그러한 모호성을 피하는 데 더 뉘앙스가있는 접근법이 있습니까?
컨텍스트는 큰 라이브러리의 네임 스페이스 인 foo
이고 소비자 프로젝트의 네임 스페이스 인 bar
입니다 (이 문제는 실제로 나타났습니다).
다음과 같은 경우에도 동일한 오류가 발생합니다. 1. "사용"을 제거합니다. 2. 메인에서 "foo :: 사각형"을 전달합니다. 이는 [인수 종속적 조회] (http://stackoverflow.com/questions/8111677/what-is-argument-dependent-lookup-aka-adl-or-ko-ko-lookup-upup) 때문입니다. 또한 템플릿 함수에서 bar :: BuildStream()을 명시 적으로 호출하면 컴파일 오류가 수정됩니다. –
인수 의존 검색에 대한 링크를 제공해 주셔서 감사합니다. 이것이 (다소 불행한) 행동을 설명하기위한 올바른 미묘한 토론입니다. –