为什么不将自动向下转换应用于模板函数?
Why isn't automatic downcasting applied to template functions?
有人问 关于字符串追加的问题。 string s; s = s + 2;
没有编译。人们给出的答案是 operator+
被定义为模板函数而 operator+=
不是,因此不应用自动向下转换(int(2)
到 char(2)
)。
原型是
template<typename _CharT, typename _Traits, typename _Alloc>
class basic_string{
basic_string&
operator+=(_CharT __c);
};
template<typename _CharT, typename _Traits, typename _Alloc>
inline basic_string<_CharT, _Traits, _Alloc>
operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs);
为什么编译器不能只使用这个原型并将 int(2) 转换为 char(2)?
basic_string<char, _T, _A> operator+(const basic_string<char, _T, _A>, char);
编译器 (G++ 6.3.0) 抱怨
[Note] deduced conflicting types for parameter '_CharT' ('char' and 'int')
主要区别在于,对于 operator +=
变体,std::basic_string
的 char 类型模板参数及其 RHS 的参数类型已固定为 char
,而 operator+
模板必须从其参数中推断出它。
因此,对于 +=
的情况,编译器知道你 "want" int
->char
转换,那里没有什么可以推断的。
另一方面,对于 operator+
情况,编译器正在查看模板
template<class CharT, class Traits, class Alloc>
basic_string<CharT,Traits,Alloc>
operator+( const basic_string<CharT,Traits,Alloc>& lhs,
CharT rhs );
并且,当试图确定 CharT
应该是什么时,它从第一个操作数得到 CharT = char
(因为 std::string
是 std::basic_string<char>
)和 CharT = int
来自第二个操作数。这样的冲突被标准定义为编译错误
有人问 string s; s = s + 2;
没有编译。人们给出的答案是 operator+
被定义为模板函数而 operator+=
不是,因此不应用自动向下转换(int(2)
到 char(2)
)。
原型是
template<typename _CharT, typename _Traits, typename _Alloc>
class basic_string{
basic_string&
operator+=(_CharT __c);
};
template<typename _CharT, typename _Traits, typename _Alloc>
inline basic_string<_CharT, _Traits, _Alloc>
operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs);
为什么编译器不能只使用这个原型并将 int(2) 转换为 char(2)?
basic_string<char, _T, _A> operator+(const basic_string<char, _T, _A>, char);
编译器 (G++ 6.3.0) 抱怨
[Note] deduced conflicting types for parameter '_CharT' ('char' and 'int')
主要区别在于,对于 operator +=
变体,std::basic_string
的 char 类型模板参数及其 RHS 的参数类型已固定为 char
,而 operator+
模板必须从其参数中推断出它。
因此,对于 +=
的情况,编译器知道你 "want" int
->char
转换,那里没有什么可以推断的。
另一方面,对于 operator+
情况,编译器正在查看模板
template<class CharT, class Traits, class Alloc>
basic_string<CharT,Traits,Alloc>
operator+( const basic_string<CharT,Traits,Alloc>& lhs,
CharT rhs );
并且,当试图确定 CharT
应该是什么时,它从第一个操作数得到 CharT = char
(因为 std::string
是 std::basic_string<char>
)和 CharT = int
来自第二个操作数。这样的冲突被标准定义为编译错误