c – 为什么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拒绝转换,声称没有匹配的运算符&gt ;::

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.

为什么?为什么查找失败?

解决方法

由于呼叫操作符>>由boost :: lexical_cast<>函数模板,运算符的第二个参数>>是 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查找.

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

运算符>>(std :: istream& is,N :: alarm_code_t& code)未在命名空间N中声明,因此ADL找不到.

这些名称查找的怪异记录在N1691 Explicit Namespaces.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...