While attempting to add support for UTF-8 locales in a library, I added
the type std::wstring
to the boost::variant
that holds a value.
At that point, I start to get errors with something down inside boost::variant
:
Blockquote/opt/TWWfsw/libboost147/include/boost/variant/detail/variant_io.hpp: In member function 'void boost::detail::variant::printer::operator()(const T&) const [with T = std::basic_string, std::allocator >, OStream = std::basic_ostream >]':
/opt/TWWfsw/libboost147/include/boost/variant/variant.hpp:858: instantiated from 'typename Visitor::result_type boost::detail::variant::invoke_visitor::internal_visit(T&, int) [with T = const std::basic_string, std::allocator >, Visitor = boost::detail::variant::printer > >]'
< SNIP SNIP >
Cursor.H:84: instantiated from here /opt/TWWfsw/libboost147/include/boost/variant/detail/variant_io.hpp:64: error: no match for 'operator<<' in '((const boost::detail::variant::printer > >)this)->boost::detail::variant::printer > >::out_ << operand'
/opt/TWWfsw/gcc44/include/c++/ostream:108: note: candidates are: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>& ()(std::basic_ostream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits]
etc.
This example is using boost-1.47 w/ g++ 4.4.
#include <string>
#include <iostream>
#include <boost/variant.hpp>
#define NO_STRING 1
int main (int argc, char** argv)
{
#if defined(NO_STRING)
boost::variant<int, std::wstring> v;
#else
boost::variant<int, std::wstring, std::string> v;
#endif
v = 3;
std::wcout << v << std::endl;
std::wstring T(L"wide char literal");
v = T;
std::wcout << v << std::endl;
return 0;
}
This program will output:
3
wide char literal
but if the #define
is removed, and both string
and wstring
are in the variant template parameters, the same error results.
My question is, can I create something that will satisfy this missing definition, like a template specialization?
Perhaps defining a variant visitor that converts the wide string to a narrow string? (not a general solution, but narrowing would work in my case)
The problem comes from using <<
with the variant when both strings are defined. Even if I only output the int through the variant, it won't compile.