I have following code:
template <typename T>
struct wrapper {
T t;
operator T() { return t; }
T get() { return t; }
};
int main() {
int a[10];
int* x = a;
wrapper<long unsigned int> y{2};
std::cout << (x + y); // warning
}
当我使用gcc编译它(在7.3.0和8.2.0上进行了测试),并加上-Wsign-conversion
参数时,我会收到警告:“warning: conversion to 'long int' from 'long unsigned int' may change the sign of the result”。如果y
的类型是long unsigned int
,则不会有警告。而且,当我明确调用y.get()
时,也没有警告:
std::cout << (x + y.get()); // this is ok
为什么会这样呢?使用用户定义转换时,是否有一些指针算术无法使用的特殊规则?
x + y
,会执行重载决议并选择内置候选项T* operator+(T*, std::ptrdiff_t);
。然而,从long unsigned int
到std::ptrdiff_t
的转换实际上并没有发生,而 GCC 在生成警告时似乎忽略了这一点。 - cpplearnera
是数组类型。 - Igor