为什么这里不考虑 std::begin/end ?

Why isn't std::begin/end being considered here?

我有一个模板自由函数算法"contains":

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(); }

以上旨在扩展 CStringA 和 CStringW 以在其上提供 const char_type 迭代器。这通常适用于其他场景,例如 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 &)'

我猜我 运行 违反了这里的一些命名空间规则。

我正在将我的自定义库代码移动到 namespace Toolbox - 包括 contains 模板和 begin 以及 CStringA/W 的 end .

我已经验证,如果我不定义 begin/end 的 CString 版本,上面的代码确实可以编译。因此,原始数组的 begin/end 的必要定义是 include & visible.

但我不知道为什么我的 Toolbox::contains 模板不会考虑 std::begin/end 用于这种情况 - 而是尝试为 [=25= 生成 Toolbox::begin(const CString &) ]?

using-directive的工作方式是 ([namespace.udir]/2):

A using-directive specifies that the names in the nominated namespace can be used in the scope in which the using-directive appears after the using-directive. During unqualified name lookup ([basic.lookup.unqual]), the names appear as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace. [ Note: In this context, “contains” means “contains directly or indirectly”. — end note ]

using namespace ::std; 使 ::std 的成员可见,为此目的,就好像它们是全局命名空间的成员一样。因此,根据正常的非限定查找规则,它们被命名空间 Toolbox.

中具有相同名称的任何内容隐藏