c++ - 为什么 lexical_cast 要求运算符>>位于匹配的 namespace 中?

标签 c++ c++11 boost lexical-cast

这是一个测试用例:

#include <istream>
#include <boost/lexical_cast.hpp>

namespace N {
    enum class alarm_code_t {
        BLAH
    };
}

std::istream& operator>>(std::istream& is, N::alarm_code_t& code)
{
    std::string tmp;
    is >> tmp;

    if (tmp == "BLAH")
        code = N::alarm_code_t::BLAH;
    else
        is.setstate(std::ios::failbit);

    return is;
}

int main()
{
    auto code = boost::lexical_cast<N::alarm_code_t>("BLAH");
}

Boost 拒绝转换,声称没有匹配的 operator>>:

In file included from /usr/local/include/boost/iterator/iterator_categories.hpp:22:0,
                 from /usr/local/include/boost/iterator/iterator_facade.hpp:14,
                 from /usr/local/include/boost/range/iterator_range_core.hpp:27,
                 from /usr/local/include/boost/lexical_cast.hpp:30,
                 from main.cpp:2:
/usr/local/include/boost/lexical_cast/detail/converter_lexical.hpp: In instantiation of 'struct boost::detail::deduce_target_char_impl<boost::detail::deduce_character_type_later<N::alarm_code_t> >':
/usr/local/include/boost/lexical_cast/detail/converter_lexical.hpp:270:89:   required from 'struct boost::detail::deduce_target_char<N::alarm_code_t>'
/usr/local/include/boost/lexical_cast/detail/converter_lexical.hpp:404:92:   required from 'struct boost::detail::lexical_cast_stream_traits<const char*, N::alarm_code_t>'
/usr/local/include/boost/lexical_cast/detail/converter_lexical.hpp:465:15:   required from 'struct boost::detail::lexical_converter_impl<N::alarm_code_t, const char*>'
/usr/local/include/boost/lexical_cast/try_lexical_convert.hpp:174:44:   required from 'bool boost::conversion::detail::try_lexical_convert(const Source&, Target&) [with Target = N::alarm_code_t; Source = char [5]]'
/usr/local/include/boost/lexical_cast.hpp:42:60:   required from 'Target boost::lexical_cast(const Source&) [with Target = N::alarm_code_t; Source = char [5]]'
main.cpp:25:60:   required from here
/usr/local/include/boost/lexical_cast/detail/converter_lexical.hpp:243:13: error: static assertion failed: Target type is neither std::istream`able nor std::wistream`able
             BOOST_STATIC_ASSERT_MSG((result_t::value || boost::has_right_shift<std::basic_istream<wchar_t>, T >::value),

( demo )

但是,当我在命名空间 N 中声明/定义 operator>> 时,代码会像宣传的那样工作。

这是为什么呢?为什么查找会失败?

最佳答案

自从调用 operator>>boost::lexical_cast<> 制成函数模板,operator>> 的第二个参数是 dependent name :

Lookup rules

As discussed in lookup, the lookup of a dependent name used in a template is postponed until the template arguments are known, at which time

  • non-ADL lookup examines function declarations with external linkage that are visible from the template definition context

  • ADL examines function declarations with external linkage that are visible from both the template definition context and the template instantiation context

(in other words, adding a new function declaration after template definition does not make it visible, except via ADL)... The purpose of this is rule is to help guard against violations of the ODR for template instantiations.

换句话说,非 ADL 查找不是从模板实例化上下文执行的。

不考虑全局命名空间,因为调用的所有参数都与全局命名空间没有任何关联。

operator>>(std::istream& is, N::alarm_code_t& code)未在命名空间 N 中声明,因此 ADL没有找到它。


这些名称查找异常记录在 N1691 Explicit Namespaces 中.

关于c++ - 为什么 lexical_cast 要求运算符>>位于匹配的 namespace 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38957531/

相关文章:

java - 使用 SWIG 生成 Java 接口(interface)

c++ - 这几行代码作为C++中的一个小测试框架有什么用呢?

c++ - C++中最大的数据类型是什么

c++ - 打开给定文件夹中的所有文本文件

c++ - 通过 boost::asio::tcp::ip 发送的大正文

c++ - 为什么调用基类析构函数会导致程序崩溃?

c++ - 如何在 C/C++ 中检查字符串中的模式?

c++ - 为什么 CLS() 在 C++11 中有不同的含义

c++ - std::map of boost::mutex 具有奇怪的行为

c++ - 关于 --> 在 C++ 中的混淆?