微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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.

原文地址:https://www.jb51.cc/c/112106.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐