我有一个模板免费功能算法"包含":
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]
我从编译器获得的消息是它无法专门化函数模板&amp;仅列出上面找到的专业。
这里有确切的信息:
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
以及end
用于CStringA / W. / p>
我已经验证过,如果我只是不定义上述代码编译的我的CString
版本的begin / end。因此,原始数组的开始/结束的必要定义包括&amp;可见。
但我不知道为什么我的Toolbox::contains
模板在这种情况下不会考虑std::begin/end
- 而是试图为{{Toolbox::begin(const CString &)
生成kPackFiles
1}}?
答案 0 :(得分:2)
using-directive 的工作方式是([namespace.udir]/2):
为此,{p>using-directive 指定指定命名空间中的名称 可以在 using-directive 之后出现的范围内使用 using-directive 。在不合格的名称查找期间 ([basic.lookup.unqual]),名称显示为声明它们 包含两者的最近的封闭命名空间 using-directive 和指定的命名空间。 [注意:在此背景下, “包含”表示“直接或间接包含”。 - 结束记录]
using namespace ::std;
使::std
的成员可见,就好像它们是全局命名空间的成员一样。因此,根据正常的非限定查找规则,它们被命名空间Toolbox
中具有相同名称的任何内容隐藏。