- 主题:C(x),C{x},C({x}),C={x},C=x的语义竟然都不完全一样
C是构造函数。
有时候有相同的效果,有时候又不一样,C++真是神奇的语言
--
FROM 223.72.62.*
chatgpt:
C++ 的构造函数语法确实很灵活,允许不同的初始化方式,每种方式在某些情况下可能会表现出细微的差异。以下是这几种构造方式的详细说明:
C(x):
这被称为圆括号初始化(也叫函数式初始化)。
最常见的方式,用于调用构造函数。
对于单参数类型,这种语法可以产生窄化转换问题,比如 int 转 double 时会有编译错误。
C{x}:
这被称为大括号初始化(列表初始化或统一初始化)。
优点是能够避免窄化转换的发生,因为它会在编译时进行更严格的类型检查。
如果 x 的类型不匹配目标类型,编译器会报错。
C({x}):
这实际上是一个复合初始化语法,可以传递列表初始化({x})给构造函数。
在接受 std::initializer_list 参数的构造函数中,这种方式非常常见。
C={x}:
这是拷贝列表初始化(copy-list-initialization)。
在某些情况下,它的行为类似于 C{x},但它主要用于直接赋值的初始化方式。
如果 C 不是 explicit 的话,允许隐式转换。
C=x:
这是赋值初始化(copy-initialization)。
主要用于非 explicit 构造函数,编译器会尝试使用可以接受 x 的构造函数,或调用可以将 x 转换为目标类型的转换构造函数。
由于 C++ 的语法历史悠久且多样,这种多种初始化方式虽然灵活但有时可能会造成混淆。C++11 引入的统一初始化 {} 提供了更一致的方式,一般推荐使用 C{x} 以避免潜在的窄化转换问题。
--
FROM 114.241.228.*
不对吧?int转double有窄化问题?会报错?
【 在 z16166 的大作中提到: 】
: chatgpt:
: C++ 的构造函数语法确实很灵活,允许不同的初始化方式,每种方式在某些情况下可能会表现出细微的差异。以下是这几种构造方式的详细说明:
: C(x):
: ...................
--
FROM 222.128.5.*
double转int,它说反了
【 在 gameplayer 的大作中提到: 】
: 不对吧?int转double有窄化问题?会报错?
:
--
FROM 114.241.228.*
其实很简单,{}提示编译器不用呼叫函数,也就是说不用通过函数指针跳转,复制形参实参哪些,()是一个彻底的函数呼叫。
--
FROM 60.191.0.*
{}本身数学上定义就是集合,所以{}的构造基本就是把一堆数直接扔到内存位置填充,所以{}对class有定义要求。
--
FROM 60.191.0.*
这个说法不太准确。
对于没有定义构造函数的pod类型,是你说的这样。
对于定义了构造函数的类型,编译器要找匹配的构造函数。
对于没有定义构造函数的非pod类型,无法使用{}这样的初始化。
【 在 ziqin 的大作中提到: 】
: 其实很简单,{}提示编译器不用呼叫函数,也就是说不用通过函数指针跳转,复制形参实参哪些,()是一个彻底的函数呼叫。
--
FROM 223.72.62.*
这个规则要区分 T x{} 和 T x={} 吗?
【 在 finlab 的大作中提到: 】
: 标 题: Re: C(x),C{x},C({x}),C={x},C=x的语义竟然都不完全一样
: 发信站: 水木社区 (Mon Nov 11 18:14:57 2024), 站内
:
: 对于没有定义构造函数的pod类型,是你说的这样。
: 对于定义了构造函数的类型,编译器要找匹配的构造函数。
: 对于没有定义构造函数的非pod类型,无法使用{}这样的初始化。
--
FROM 120.253.228.*
这些对class的具体要求,本质上是为了template programming的时候兼容{}和(),因为某个类可能需要使用{},或者需要使用(),采用传统的if constexpr type_traits太丑陋,所以在编译器层面把调用{}或者()语法化
但是{}的本质,是ctor的direct placement
对于很多会被高频构造的数据struct,{}和构造函数能相差一个数量级的速度
【 在 finlab 的大作中提到: 】
: 这个说法不太准确。
: 对于没有定义构造函数的pod类型,是你说的这样。
: 对于定义了构造函数的类型,编译器要找匹配的构造函数。
: ...................
--
FROM 115.205.236.*
G家standard说的比较明确,除非自己在写template,否则一般使用中,除非是fill data struct/container的操作,其他都应该明确使用()而不是{},这样让读代码的人知道这个构造函数中干了别的复杂的事
--
FROM 115.205.236.*