Reputation: 1766
I know that a std::ref(object) creates a std::reference_wrapper(object), and that std::reference_wrapper has a non-explicit type conversion operator member function
operator T&() const
and I know that this influences how I use it when template parameter deduction comes into play: so in Print below, the type T of the argument is deduced as std::reference_wrapper if I call it with,say, std::ref("hello")
template <class T>
void Print(T t)
{
std::cout << t << std::end;
}
Why doesn't this line compile?
std::string s = "hello";
std::cout << std::reference_wrapper<std::string>(s) << std::endl;
the instantiated specialization should have a
operator std::string&() const
type conversion function, so why can't I use a reference wrapper like this?
Upvotes: 0
Views: 222
Reputation: 22152
The operator<<
overload that you are trying to use has the following form (from cppreference.com):
template <class CharT, class Traits, class Allocator> std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const std::basic_string<CharT, Traits, Allocator>& str);
The second function parameter contains template parameters and is not a non-deduced context. Therefore it must deduce the template arguments. Implicit conversions are not considered for template argument deduction and since std::reference_wrapper
is not a std::basic_string
, deduction will fail. It doesn't matter whether std::reference_wrapper
can be converted to std::string
(or a reference to one).
And just to clarify, std::string
is an alias for the specialization std::basic_string<char, std::char_traits<char>, std::allocator<char>>
of std::basic_string
. std::basic_string
can be specialized for any character type, for example wchar_t
(which is aliased as std::wstring
). Other specializations are simply not often used.
Upvotes: 1