2016-10-20 2 views
0

나는 템플릿 무료 기능 알고리즘은 "포함"있습니다std :: begin/end가 여기에서 고려되지 않는 이유는 무엇입니까?

이 다음과 같은 사항에 대해 작동 또는 범위에 무엇이에 따라 다음 실패
template <typename collection_type, typename element_type, typename comparison_function_type> 
bool contains(const collection_type & collection, const element_type & element, comparison_function_type comparison_function) 
{ 
    using namespace ::std; 
    return end(collection) != find_if(begin(collection), end(collection), [&](const element_type & candidate) { return comparison_function(candidate, element); }); 
} 

:

 static const TCHAR * kPackFiles[] = { _T("boxit"), _T("pack") }; 
     const auto & name = filename.GetName(); 
     if (contains(kPackFiles, name, Toolbox::case_insensitive_equal_to<Toolbox::TCHARStringPolicy>())) 
       do_something_interesting(); 

위의 컴파일 다음이 아닌 경우 범위 내에 :

template <typename T> 
const typename ::std::enable_if<::std::is_same<T, CStringA>::value || ::std::is_same<T, CStringW>::value, T>::type::XCHAR * 
    begin(const T & str) { return str.GetString(); } 

template <typename T> 
const typename ::std::enable_if<::std::is_same<T, CStringA>::value || ::std::is_same<T, CStringW>::value, T>::type::XCHAR * 
    end(const T & str) { return str.GetString() + str.GetLength(); } 

위의 내용은 const char_type 반복기를 제공하기 위해 CStringA 및 CStringW를 확장하기위한 것입니다. 이것은 일반적으로 for (c : my_cstring) cout << c;

같은 다른 시나리오에 대한 작동하지만 위의 경우에 - 나는 그것이 함수 템플릿 &을 전문으로하는 데 실패 컴파일러에서 메시지를받을 collection_type=const TCHAR *[2] 이상에서만 볼 수있는 전문화를 나열합니다.

여기에 정확한 메시지입니다 :

error C2893: Failed to specialize function template 'const ::std::enable_if<std::is_same<T,CStringA>::value||std::is_same<T,CStringW>::value,T>::type::XCHAR *Toolbox::end(const T &)' 

그리고 난 여기에 몇 가지 네임 스페이스 규칙에 대해 최대 실행했습니다 같은데요. contains 템플릿과 begin 및 CStringA/W에 대한 end 모두 포함 -

나는 namespace Toolbox에 내 사용자 지정 라이브러리 코드를 이동하는 중간에 있어요.

위의 코드가 컴파일하는 begin/end 버전 CString을 정의하지 않으면 확인했습니다. 따라서 원시 배열의 begin/end에 대한 필요한 정의에는 &이 표시됩니다.

하지만 내 Toolbox::contains 템플릿이 사건에 대한 std::begin/end을 고려하지 않을 이유에 손실에있어 - 대신하고 kPackFiles에 대한 Toolbox::begin(const CString &)을 생성하려고?

답변

2

방법 사용 지시어의 작업 ([namespace.udir]/2)이다

사용하는 후보 공간 의 이름 범위에서 사용할 수 있음을 지정하여 지시어 방향지시어 다음에 나타납니다. 정규화되지 않은 이름 조회 ([basic.lookup.unqual]) 중에 이름은 에 사용 방향과 지정된 네임 스페이스를 모두 포함하는 가장 가까운 포함하는 네임 스페이스로 선언 된 것처럼 나타납니다. [참고 :이 문맥에서 "포함"은 "직접 또는 간접적으로 포함"을 의미합니다. - 엔드 노트] 그들이 전역 네임 스페이스의 멤버 인 것처럼

using namespace ::std;는,이 목적을 위해, 볼 수 있도록 ::std의 구성원이 발생합니다. 따라서 정규 무 규정 조회 규칙에 따라 Toolbox 네임 스페이스에 같은 이름의 항목이 숨겨집니다.

+0

'포함'이 하위 네임 스페이스에있는 경우에도 동일하게 유지됩니까? 따라서 std와 toolbox가 로컬 네임 스페이스가 아닙니다 (예 : toolbox :: algorithms)? 또는 도구 상자의 내용이 std보다 '가까이'남아 있습니까? – Mordachai

+0

같은. 당신은 당신이 어디에 있는지, 당신이 이름을 찾을 때까지 한 번에 한 단계 위로 올라간 다음에 멈 춥니 다. –

+0

나는 C++의 이름 검색이 싫다. : P – Mordachai