为什么不在这里考虑std :: begin / end? [英] Why isn't std::begin/end being considered here?

查看:160
本文介绍了为什么不在这里考虑std :: begin / end?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模板自由函数算法包含:

I have a template free function algorithm "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); });
}

这适用于以下情况,或者对于以下内容失败,具体取决于范围:

This works for the following or fails for the following depending on what's in scope:

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

以上编译除非以下内容在以下范围内:

The above compiles unless the following is in scope:

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;

The above is intended to extend CStringA and CStringW to offer const char_type iterators on them. This generally works for other scenarios such as for (c : my_cstring) cout << c;

但对于上述情况 - 其中 collection_type = const TCHAR * [2] 我从编译器那里得到的消息是它没有专门化功能模板&只列出上面找到的专业。

But for the above case - where collection_type=const TCHAR *[2] I get messages from the compiler that it failed to specialize function template & only lists the specializations found above.

以下是确切消息:

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 &)'

我猜这个我在这里遇到了一些命名空间规则。

And I'm guessing that I've run up against some namespace rules here.

我正在将自定义库代码移动到命名空间工具箱 - 包括包含模板和开始结束 for CStringA / W。

I'm in the midst of moving my custom library code into namespace Toolbox - including both contains template and begin and end for CStringA/W.

我已经验证过,如果我只是没有定义我的 CString 版本上面的代码编译的开始/结束。因此,原始数组的开始/结束的必要定义包括&可见。

I've verified that if I simply don't define my CString versions of begin/end that the above code does compile. So the necessary definition of begin/end for raw arrays is include & visible.

但我不知道为什么我的 Toolbox :: contains 模板不会考虑对于这种情况, std :: begin / end - 而是尝试生成 Toolbox :: begin(const CString&) for kPackFiles

But I'm at a loss as to why my Toolbox::contains template won't consider std::begin/end for this case - and instead tries to generate Toolbox::begin(const CString &) for kPackFiles?

推荐答案

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


using-directive 指定可以使用指定命名空间
中的名称在 using-directive 之后出现 using-directive 的范围内。在非限定名称查找
([basic.lookup.unqual])期间,名称显示为在
中声明最近的封闭命名空间,其中包含
using-directive 和指定的命名空间。 [注意:在此上下文中,
包含表示直接或间接包含。 - 结束注释]

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 ]

使用namespace :: std; 使 :: std 的成员可见,就好像它们是全局命名空间的成员一样。因此,根据正常的非限定查找规则,它们在命名空间工具箱中具有相同名称的任何内容都是隐藏的。

using namespace ::std; causes the members of ::std to be visible, for this purpose, as if they were members of the global namespace. They are therefore hidden, per the normal unqualified lookup rules, by anything with the same name in the namespace Toolbox.

这篇关于为什么不在这里考虑std :: begin / end?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆