我有以下使用模板的C++11代码:
struct Base{
using count_type = unsigned short;
};
template<class T>
struct A : public Base{
using count_type = A::count_type;
// not works even if I comment this
count_type add(T x){
count_type sum = 5;
sum += x.value();
//sum += (count_type) x.value(); // not works even if I cast this, e.g.
return sum;
}
};
struct B{
using count_type = A<B>::count_type;
count_type value(){
return 5; // not works even if I do:
//return (count_type) 5;
//return 5U;
}
};
int main(int argc, char *argv[]){
B b;
A<B> a;
a.add(b);
}当我尝试用-Wconversion编译时,会收到奇怪的错误消息:
$ g++ -std=c++11 -Wconversion x.cc
x.cc: In instantiation of ‘A<T>::count_type A<T>::add(T) [with T = B; A<T>::count_type = short unsigned int]’:
x.cc:29:9: required from here
x.cc:11:7: warning: conversion to ‘A<B>::count_type {aka short unsigned int}’ from ‘int’ may alter its value [-Wconversion]
sum += x.value();
^为什么会发生这种事?哪里都没有int?
如果有人修改我的问题,我将不胜感激。
注意:clang没有给出这样的警告。
发布于 2015-12-13 15:05:23
sum += x.value();的意思是(粗略地) sum = sum + x.value();这里的RHS,sum + x.value(),添加两个unsigned short值并生成一个int。将该int重新分配给unsigned short可以更改其值。
在我看来,这个警告并不特别有用,我建议关闭它,但是如果您出于某种原因想要保持它的启用,请在这里写一个强制转换:
sum = (count_type) (sum + x.value());或
sum = static_cast<count_type>(sum + x.value());发布于 2015-12-13 15:06:30
根据隐式提升,任何算术表达式(如sum = sum + x.value())都会经历一种称为通常算术转换的模式,这是标准第5节中的相关部分:
..。 -否则,整体提升(4.5)应在两个操作数上执行。59 .然后,下列规则应适用于促进的操作数:
整体晋升规定:
如果int可以表示源类型的所有值,则其整数转换秩(4.13)小于int的整数类型( bool、char16_t、char32_t或wchar_t )以外的整数类型的prvalue可以转换为类型的prvalue;否则,可以将源prvalue转换为无符号int类型的prvalue。
因此,操作数被转换为int,然后返回到unsigned short。这是因为转换级别指定
有符号整数类型的秩应大于任何大小较小的有符号整数类型的秩。
和
任何无符号整数类型的秩应等于相应有符号整数类型的秩。
https://stackoverflow.com/questions/34252403
复制相似问题