Похоже на проблему с компилятором / ошибка
(спасибо @liliscent за исправление того, что я здесь говорил ранее)
Сначала давайте сделаем один MCVE для всех заявлений, которые вы упоминали:
#include <iostream>
template <typename T>
struct wrapper {
T t;
operator T() const { return t; }
T get() const { return t; }
};
int main() {
int a[10];
int* x { a } ;
wrapper<long int> y1{2};
wrapper<unsigned int> y2{2};
wrapper<long unsigned int> y3{2};
std::cout << (x + y1) << '\n';
std::cout << (x + y2) << '\n';
std::cout << (x + y3) << '\n'; // this triggers a warning
std::cout << (x + y3.get()) << '\n';
}
и, используя GCC 8.2.0, мы получаем :
<source>: In function 'int main()':
<source>:20:23: warning: conversion to 'long int' from 'long unsigned int' may change the sign of the result [-Wsign-conversion]
std::cout << (x + y3) << '\n';
^~
Compiler returned: 0
по ссылке,вы увидите, как:
- GCC выдает эту ошибку со всеми (недавними) версиями.
- Clang выдает эту ошибку с версией 6.0.
- Clang делает not выдает эту ошибку с версией 7.0.
Так что это должен быть некоторый угловой случай с соответствием стандартам.
... но не входите в "Here Be Dragons""территория.
Теперь я уверен, что есть сложное техническое объяснение того, почему вы получаете ошибку только в 3-м из этих потоковых операторов.Но я утверждаю, что не имеет значения с точки зрения практического использования.Если вы будете только добавлять правильные целые числа в указатели - как вы делаете с оператором .get()
- вы не получите это предупреждение.
Видите ли, вы пытаетесь добавить пользовательский тип вуказатель - который не имеет большого смысла вообще.Это правда, что ваша структура может быть преобразована в целое число, но полагаясь на то, что это преобразование будет выполнено неявно открывает вам такие вещи, как выбор преобразования другого операнда или другие пути преобразования, которые вы не рассматривали.Более того, это случаи, когда вы можете «нажать» на какое-то эзотерическое предложение в стандарте относительно того, когда неявные преобразования являются законными, что может или не может быть реализовано с абсолютной корректностью компилятором (см. Комментарий @ cppcleaner).
Так что просто используйте x + y3.get()
в своем коде, и вам не придется беспокоиться об этих эзотерических угловых случаях.
Я приводил аналогичный аргумент в этом ответе относительно использованияиндекс 0 пустой строки (да, это так).