std::ref 隐式转换为引用混淆
std::ref implicit conversion to reference confusion
我知道 std::ref(object) 创建了一个 std::reference_wrapper(object),并且 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
)。其他专业根本不经常使用。
我知道 std::ref(object) 创建了一个 std::reference_wrapper(object),并且 std::reference_wrapper 有一个不明确的类型转换运算符成员函数
operator T&() const
而且我知道这会影响我在模板参数推导发挥作用时使用它的方式: 所以在下面的 Print 中,如果我用 std::ref("hello")
调用它,则参数的类型 T 被推断为 std::reference_wrappertemplate <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
)。其他专业根本不经常使用。