Ответ 1
В вашем первом примере разрешению перегрузки разрешено находить ваш operator+
:
[C++14: 13.3.1.2/2]:
Если любой из операндов имеет тип, который является классом или перечислением, может быть объявлена определяемая пользователем операторная функция, которая реализует этот оператор, или может потребоваться определенное пользователем преобразование преобразуйте операнд в тип, подходящий для встроенного оператора. В этом случае разрешение перегрузки используется для определения того, какая операторная функция или встроенный оператор должны быть вызваны для реализации оператора. [..]
[C++14: 13.3.2/1]:
Из набора функций-кандидатов, построенных для данного контекста (13.3.1), выбирается набор жизнеспособных функций, из которых лучшая функция будет выбрана путем сравнения преобразования аргументов последовательности для наилучшего соответствия (13.3.3). Выбор жизнеспособных функций рассматривает отношения между аргументами и функциональными параметрами, отличными от ранжирования последовательностей преобразования.
[C++14: 13.3.2/2]:
Во-первых, , чтобы быть жизнеспособной функцией, функция-кандидат должна иметь достаточно параметров для согласования числа с аргументами в списке.
- Если в списке есть аргументы
m
, все кандидатские функции, имеющие точноm
параметры, жизнеспособны.- [..]
[C++14: 13.3.2/3]
: Во-вторых, дляF
для жизнеспособной функции для каждого аргумента будет существовать неявная последовательность преобразований (13.3.3.1), которая преобразует этот аргумент в соответствующий параметрF
. [..]
(Вы можете сами изучить формулировку "неявной последовательности преобразований", чтобы увидеть, что вызов operator+
допустим, правила слишком подробные, чтобы гарантировать вербальное воспроизведение здесь.)
Однако во втором примере разрешение перегрузки ограничено базовым механизмом арифметического добавления (который не определен для const char[N]
или const char*
), фактически запрещающий рассматривать любую функцию operator+
:
[C++14: 13.3.1.2/1]:
Если никакой операнд оператора в выражении не имеет тип, который является классом или перечислением, оператор считается встроенным оператором и интерпретируется в соответствии с пунктом 5.
[C++14: 5.7/1]:
[..] Для добавления оба операнда должны иметь арифметический или неперечисленный тип перечисления, или один операнд должен быть указателем на полностью определенный тип объекта, а другой должен иметь интегральный или неперечисленный тип перечисления. [..]
[C++14: 5.7/3]:
Результатом двоичного + оператора является сумма операндов.