C++ 为什么我会收到Wsign转换警告?
我有以下代码:C++ 为什么我会收到Wsign转换警告?,c++,c++11,gcc,type-conversion,implicit-conversion,C++,C++11,Gcc,Type Conversion,Implicit Conversion,我有以下代码: 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); // warni
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
}
为什么会这样?在使用用户定义的转换时,是否有一些指针算法的特殊规则不能使用 似乎是编译器问题/错误
(感谢@liliscent纠正我之前在这里说的话)
首先,让我们为您提到的所有声明制作一张单张:
#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';
}
#包括
模板
结构包装器{
T;
运算符T()常量{return T;}
T get()常量{return T;}
};
int main(){
INTA[10];
int*x{a};
包装y1{2};
包装y2{2};
包装y3{2};
std::cout注意,IIRC,指针算法仅为数组元素定义。对于x+y
,执行重载解析,并使用内置的候选T*运算符+(T*,std::ptrdiff\u T);
被选中。但是,GCC在生成警告时似乎忽略了这一点。@DanielLangr对,我对问题进行了编辑,因此a
现在是数组类型。我担心这不会回答发布的问题。我完全理解这是答案的第二部分,第一部分会解释原因。所以答案是“这就是为什么;但是请做一些理智的事情,像这样。”但是没有第一部分,这不是答案。理解为什么会发生事情比“一个因为它发生而起作用的解决方案”更有价值@Angew:在某些情况下,理解为什么会发生某些事情是有价值的。在这种情况下,我认为不理解为什么会发生这些事情是有价值的(除非你是在探索GCC的行为,而不是编写C++)。但我会尝试稍微编辑以强调这一点。@Angew…但还是在答案中添加了第一部分。看起来clang并没有警告您-->错误。您应该通过-Wsign conversion
来启用警告,或者-Weverything
@einpoklum警告存在于clang 6.0中,而不是7.0中。可能是错误。
#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';
}
<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