c – 为什么lexical_cast要求操作符>>在匹配的命名空间中?

前端之家收集整理的这篇文章主要介绍了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&C++相关文章