我使用模板跟随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
不会发出此类警告。
答案 0 :(得分:1)
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());
答案 1 :(得分:1)
根据隐式促销,任何算术表达式(如sum = sum + x.value()
)都会经历称为通常的算术转换的模式,标准的第5节中的相关部分:
...
- 否则,将对两个操作数执行整数促销(4.5)。 59然后,以下规则应适用于晋升的操作数:
整体促销指定:
bool,char16_t,char32_t或wchar_t 之外的整数类型的prvalue,其整数转换等级(4.13)小于int的等级,可以转换为
int
类型的prvalue < / strong>如果int可以表示源类型的所有值;否则,源prvalue可以转换为unsigned int类型的prvalue。
因此操作数转换为int
,然后转换为unsigned short
。这是因为转换排名指定了
有符号整数类型的等级应大于任何有符号整数类型的等级。
和
任何无符号整数类型的等级应等于相应的有符号整数类型的等级。