Oto testcase:Dlaczego funkcja lexical_cast wymaga, aby operator >> znajdował się w pasującym obszarze nazw?
#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");
}
doładowania odrzuca konwersję, twierdząc, że nie ma dopasowania 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)
Jednak kod działa jak reklamowane kiedy zadeklaruj/zdefiniuj operator>>
wewnątrz przestrzeni nazw N
.
Dlaczego tak jest? Dlaczego wyszukiwanie kończy się niepowodzeniem?
Bog-standardowy problem z ADL? –
@ T.C .: Hmm ... inne 'operator >>' znalezione w przestrzeni nazw 'N' więc nie przeszukano globalnej przestrzeni nazw i nie znaleziono tego konkretnego' operatora >> '? Ale nie mam innego 'operatora >>' w 'N'. Lub w rzeczywistości. Nie mogę zgadnąć, skąd się bierze ADL. –
ADL wchodzi w to, ponieważ twoim drugim parametrem 'operator >>' jest 'N :: alarm_code_t', więc' N' jest skojarzoną przestrzenią nazw i zostanie przeszukana dla definicji operatora. – Praetorian