Почему автоматическое понижение рейтинга не применяется к функциям шаблона?

Кто-то задал этот вопрос о добавлении строки. Это 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')

1 ответ

Решение

Главное отличие в том, что для operator += вариант, аргумент шаблона типа char для std::basic_stringи, следовательно, тип аргумента для его RHS, уже зафиксирован на char, в то время как operator+ шаблон должен вывести это из своих аргументов.

Таким образом, для += В этом случае компилятор знает, что вы хотите 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 из второго операнда. Такой конфликт определен как стандартная ошибка компиляции.

Другие вопросы по тегам