- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
关闭。这个问题是opinion-based .它目前不接受答案。
想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题.
10 个月前关闭。
Improve this question
我注意到我通常使用常量引用作为返回值或参数。我认为原因是它的工作原理与在代码中使用非引用几乎相同。但它肯定需要更多空间并且函数声明变得更长。我可以接受这样的代码,但我认为有些人认为这是一种糟糕的编程风格。
你怎么看?在 int 上写 const int& 值得吗?我认为它无论如何都是由编译器优化的,所以也许我只是在浪费时间编码它,一个?
最佳答案
在 C++ 中,我认为使用 const T&
的反模式很常见。就像一个聪明的方式只是说 T
在处理参数时。然而,值和引用(无论是否为常量)是两个完全不同的东西,总是盲目地使用引用而不是值会导致微妙的错误。
原因是在处理引用时,您必须考虑两个不存在于值中的问题:生命周期和 别名 .
举个例子,应用这种反模式的地方是标准库本身,其中 std::vector<T>::push_back
接受参数 a const T&
而不是一个值,这可以在代码中反咬一口,例如:
std::vector<T> v;
...
if (v.size())
v.push_back(v[0]); // Add first element also as last element
此代码是一个定时炸弹,因为
std::vector::push_back
想要一个 const 引用,但执行 push_back 可能需要重新分配,如果发生这种情况,则意味着在重新分配后,收到的引用将不再有效(
生命周期 问题)并且您进入未定义行为领域¹。
void std::vector<T>::push_back(T x)
),然后在容器内的最终位置有效地移动该值。那么调用者最终可能会使用
std::move
如果这被认为很重要。
struct P2d
{
double x, y;
P2d(double x, double y) : x(x), y(y) {}
P2d& operator+=(const P2d& p) { x+=p.x; y+=p.y; return *this; }
P2d& operator-=(const P2d& p) { x-=p.x; y-=p.y; return *this; }
};
struct Rect
{
P2d tl, br;
Rect(const P2d& tl, const P2d& br) : tl(tl), bt(br) {}
Rect& operator+=(const P2d& p) { tl+=p; br+=p; return *this; }
Rect& operator-=(const P2d& p) { tl-=p; br-=p; return *this; }
};
该代码乍一看似乎很安全,
P2d
是一个二维点,
Rect
是一个矩形,加/减一个点意味着平移这个矩形。
myrect -= myrect.tl;
代码将不起作用,因为翻译运算符已被定义为接受(在这种情况下)引用同一实例的成员的引用。
tl -= p;
更新左上角之后左上角将是
(0, 0)
理所当然,但也
p
同时会变成
(0, 0)
因为
p
只是对左上角成员的引用,因此右下角的更新将不起作用,因为它将通过
(0, 0)
进行翻译因此基本上什么都不做。
const
这个词而误以为const引用就像一个值。 .如果您尝试使用该引用更改被引用的对象,该词的存在只是为了给您编译错误,但并不意味着被引用的对象是常量。更具体地说,const ref 引用的对象可能会更改(例如,由于别名),甚至在您使用它时可能会消失(生命周期问题)。
const T&
词
const 表示引用的属性,而不是被引用对象的属性:它是无法使用它来更改对象的属性。大概
只读 将是一个更好的名字
const IMO 有一种心理效应,即在您使用引用时插入对象将保持不变的想法。
const
对于引用意味着绝对没有对于优化器;这个词只是为了帮助程序员 - 我个人不太确定它有多大帮助,但那是另一个故事)。
push_back
不在乎
身份的对象,因此应该按值获取参数。当您将 const 引用作为值传递给函数时,您有责任确保引用的对象在函数的整个持续时间内保持事件状态。与
v.push_back(v[0])
如果没有进行预订,这只是错误的,如果发生这种情况,IMO(给定
push_back
签名)是调用者的错。然而,真正的逻辑错误是
push_back
界面设计(有意为之,在效率的祭坛上牺牲了逻辑正确性)。不确定是不是因为那个缺陷报告,但我看到一些编译器在这种特殊情况下“修复”了这个问题(即
push_back
会检查被推送的元素是否来自 vector 本身)。
关于c++ - int vs const int&,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4705593/
我正在尝试使用 y 组合器在 Scala 中定义 gcd: object Main { def y[A,B]( f : (A => B) => A => B ) : A => B = f(y(f)
我正在尝试了解返回指向函数的指针的函数,在我尝试编译代码后,它给了我这种错误: cannot convert int (*(int))(int) to int (*(int))(int) in ass
所以我一直在关注 youtube 上的游戏编程教程,然后弹出了这段代码:bufferedImageObject.getRGB(int, int, int, int, int[], int, int);
我正在将时间现在 与存储在数据库某处的时间进行比较。数据库中存储的时间格式为“yyyyMMddHHmmss”。例如,数据库可能会为存储的时间值返回 201106203354。然后我使用一个函数将时间现
例如 Maze0.bmp (0,0) (319,239) 65 120 Maze0.bmp (0,0) (319,239) 65 120 (254,243,90) Maze0.bmp (0,0) (
评论 Steve Yegge的post关于 server-side Javascript开始讨论语言中类型系统的优点和这个 comment描述: ... examples from H-M style
我正在研究 C 的指针,从 Deitel 的书中我不明白 int(*function)(int,int) 和 int*function(int, int) 表示函数时。 最佳答案 C 中读取类型的经验
您好,我使用 weblogic 11g 创建 war 应用程序,我对 joda time 的方法有疑问 new DateTime(int, int, int, int, int, int); 这抛出了
Create a method called average that calculates the average of the numbers passed as parameters. The
var a11: Int = 0 var a12: Int = 0 var a21: Int = 0 var a22: Int = 0 var valueDeterminant = a11 * a12
我正在为一个项目设置 LED 阵列。我得到了一个 LED 阵列,可以根据引脚变化电压进行更改,但我无法添加更多引脚。 当我尝试时,编译失败并显示错误:函数“int getMode(int, int,
除了创建对列表执行简单操作的函数之外,我对 haskell 还是很陌生。我想创建一个列表,其中包含 Int 类型的内容, 和 Int -> Int -> Int 类型的函数. 这是我尝试过的: dat
这个问题已经有答案了: Java add buttons dynamically as an array [duplicate] (4 个回答) 已关闭 7 年前。 StackOverFlow问题今天
我有几个 EditText View ,我想在其中设置左侧的图像,而 setCompoundDrawablesWithIntrinsicBounds 似乎不起作用。图形似乎没有改变。 有人知道为什么会
#include using namespace std; int main() { static_assert(is_constructible, int(*)(int,int)>::val
fun sum(a: Int, b: Int) = a + b val x = 1.to(2) 我在找: sum.tupled(x),或者 sum(*x) 当然,以上都不能用 Kotlin 1.1.3
有一个函数: func (first: Int) -> Int -> Bool -> String { return ? } 返回值怎么写?我对上面 func 的返回类型感到很困惑。 最
type foo = A of int * int | B of (int * int) int * int 和 (int * int) 有什么区别?我看到的唯一区别在于模式匹配: let test_
我正在尝试制作一个 slider 游戏。在这个类中,我使用 Graphics 对象 g2 的 drawImage 方法来显示“拼图”的 block 。但在绘制类方法中,我收到此错误:找不到符号方法dr
我试着理解这个表达: static Func isOdd = i => (i & 1) == 1; 但是这是什么意思呢? 例如我有 i = 3。然后 (3 & 1) == 1 或 i = 4。然后
我是一名优秀的程序员,十分优秀!