首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >任务分配和初始化期间的类型安全

任务分配和初始化期间的类型安全
EN

Stack Overflow用户
提问于 2017-07-03 12:04:47
回答 3查看 134关注 0票数 0

初始化程序列表语法的一个明显优点是,它通过禁止缩窄转换来提高类型安全性。

代码语言:javascript
复制
int x {7.9};   // error: narrowing
int y = 7.9;   // OK: y becomes 7. Hope for a compiler warning

然而,AFAIK没有办法在随后的转让中强制执行相同的检查:

代码语言:javascript
复制
int z {7};
z = 7.9;  // allows narrowing, and no other syntax available

为什么初始化时的类型安全受到语言设计的更多关注,而在赋值过程中类型安全性更高呢?任务的缩小是否不太可能导致错误和/或更难检测?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-07-03 12:11:48

如果xint变量,那么

代码语言:javascript
复制
x = 7.9;

由于向后兼容性的原因,必须在C++11和以后继续工作。即使x是大括号初始化的,情况也是如此。大括号初始化的int变量与非大括号初始化的int变量具有相同的类型.如果通过引用函数传递x

代码语言:javascript
复制
void f(int& r);
f(x);

然后,在f的主体中,将无法“判断”对象是否已被大括号初始化,因此该语言不能对其应用不同的规则。

您可以通过这样做来防止自己缩小转换:

代码语言:javascript
复制
x = {7.9};  // error

还可以尝试通过创建不允许缩小分配的int“包装器”类型来利用类型系统:

代码语言:javascript
复制
struct safe_int {
    template <class T> safe_int(T&& x) : value{std::forward<T>(x)} {}
    template <class T> safe_int& operator=(T&& x) {
        value = {std::forward<T>(x)}; return *this;
    }
    operator int() const { return value; }
    int value;
};

不幸的是,不能使该类在任何情况下都像实际的int对象那样运行。

票数 3
EN

Stack Overflow用户

发布于 2017-07-03 12:14:38

为什么初始化时的类型安全受到语言设计的更多关注,而在赋值过程中类型安全性更高呢?

不,这不是原因,是列表初始化给了您错误,例如,这也会出错:

代码语言:javascript
复制
int x = {7.8};

这是因为根据dcl.init,列表初始化中不允许缩小范围。

如果初始化-子句是表达式,并且转换表达式需要收缩转换,则程序的格式不正确。

票数 2
EN

Stack Overflow用户

发布于 2017-07-03 12:14:34

{}防止转换类型,例如doubleint,但是

()可以这样做,只能显示有关转换的警告。

你可以这样写

int z(7.9) // == 7

当您确信类中不存在带有std::initializer_list的构造函数时,可以使用括号,因为他将被执行,或者您可以delete该构造函数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44885143

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档