我知道std::ref(对象(创建了一个std::reference_wrapper(对象(,并且std::reference_wrapper有一个非显式类型转换运算符成员函数
operator T&() const
我知道当模板参数推导开始发挥作用时,这会影响我如何使用它:因此,在下面的Print中,如果我用std::ref("hello"(调用参数,则该参数的类型T被推导为std::reference_wrapper
template <class T>
void Print(T t)
{
std::cout << t << std::end;
}
为什么这行不编译?
std::string s = "hello";
std::cout << std::reference_wrapper<std::string>(s) << std::endl;
实例化的专业化应该有一个
operator std::string&() const
类型转换函数,那么为什么我不能使用这样的引用包装器呢?
您尝试使用的operator<<
重载具有以下形式(来自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);
第二个函数参数包含模板参数,不是非推导上下文。因此,它必须推导模板参数。模板参数推导不考虑隐式转换,并且由于std::reference_wrapper
不是std::basic_string
,因此推导将失败。std::reference_wrapper
是否可以转换为std::string
(或对一的引用(并不重要。
为了澄清,std::string
是std::basic_string
的特殊化std::basic_string<char, std::char_traits<char>, std::allocator<char>>
的别名。std::basic_string
可以专门用于任何字符类型,例如wchar_t
(别名为std::wstring
(。其他专业并不经常使用。