函数只接受非常量左值(Having a function only accept non-const lvalues)
我有一个函数,它将第一个向量排序为两个向量作为排序条件。 它的签名是
template<typename A, typename B> void sort(A&& X, B&& Y) { .. }
问题是通用引用会允许像这样的无意义的情况
sort(vector<int>{ 2,1,3 }, vector<int>{ 3,1,2 });
之后右值将被销毁(废话)。
明确询问左值是不起作用的
template<typename A, typename B> void sort(A& X, B& Y) ... // (*) sort(vector<int>{2,1,3}, vector<int>{3,1,2});
由于某种原因上面的编译(我认为只允许const值左右绑定到rvalues并延长它们的生命周期?)。
如果我将
const
添加到左值引用,那么函数将不再能够修改矢量并对它们进行排序。
我的问题是:
1)为什么在标有
// (*)
的示例中,我可以将rvalue绑定到一个甚至不是const
的左值? 为什么要像int& r = 20;
不允许? 有什么不同?2)我该如何解决我的问题,即让函数只接受左值而不是临时值? (如果可能的话,当然)
很明显,我可以使用任何可用的C ++版本
I have a function which sorts two vectors with the first of them as ordering criterion. Its signature is
template<typename A, typename B> void sort(A&& X, B&& Y) { .. }
The problem is that universal references would allow nonsense cases like
sort(vector<int>{ 2,1,3 }, vector<int>{ 3,1,2 });
where an rvalue will be destroyed afterwards (nonsense).
Asking explicitly for a lvalue doesn't work since
template<typename A, typename B> void sort(A& X, B& Y) ... // (*) sort(vector<int>{2,1,3}, vector<int>{3,1,2});
for some reason the above compiles (I thought only const lvalues were allowed to bind to rvalues and to prolong their lifetime?).
If I add
const
to the lvalue reference then the function will no longer be able to modify the vectors and sort them.
My questions are:
1) Why in the example marked with
// (*)
can I bind a rvalue to a lvalue that is not evenconst
? Why instead something likeint& r = 20;
isn't allowed? What's the difference?2) How can I solve my issue i.e. having the function accept only lvalues and not rvalue temporaries? (If it's possible, of course)
Obviously I'm allowed to use any C++ version available
原文:https://stackoverflow.com/questions/32720767
最满意答案
由于
$out
会将文档发送到存储引擎,因此MMAP存储引擎可以使用填充以允许自然文档增长,因此可能会与文档/ bson对象大小相关联。从汇总中删除$ out并添加此代码段将显示文档大小(您可以添加任何其他字段以获取更多诊断数据)。 当我们遇到文档适合两个其他文档之间的差距的情况时,它将被添加到那里 - 所以订单将被改变 - >这意味着$ out将保持服务器顺序,但是存储引擎可以为此添加噪声。
db.coll.aggregate([pipeline]).forEach(function(doc) { print(" _id: "+ doc._id + "\t\t size: " + Object.bsonsize(doc) ) })
解
聊天后 - 并建议从MMAP切换到WT - 查询成功运行!
As
$out
sends documents to storage engine, then there could be a shift in order connected with document/bson object size, as MMAP storage engine uses padding to allow natural document growth.removing $out from aggregate and adding this snippet will display documents size (you could add any other field to get more diagnostic data). When we will have a situation that documents fits in a gap between two other documents, then it will be added there - so order will be changed-> that means $out will preserver order, but storage engine can add a noise to that.
db.coll.aggregate([pipeline]).forEach(function(doc) { print(" _id: "+ doc._id + "\t\t size: " + Object.bsonsize(doc) ) })
Solution
after a chat - and recommendation to switch from MMAP to WT -query was ran with success!
相关问答
更多-
为什么只要将日期作为分组键的一部分,为什么每天运行它? 这是日期聚合运算符的存在,因此您可以在一段时间内按时间帧聚合而不循环: collection.aggregate([ { "$match":{ "UID": uid, "TEMP":{ "$exists": true } "site" : "SITE123", "updatedAt": { "$gte": new Date(START_DATE_ARG), ...
-
我知道这是一个老问题,但看起来似乎没有达到一个简单的答案,它涉及使用2.6中可用的表达式,所以它也会有效。 您不需要执行任何$unwind ing或复杂的$map ping,只需要在要查找匹配项的两个数组上执行$setIntersection 。 使用来自很长答案的示例数据: db.foo.aggregate( {$match:{"obj1.a":"a"}}, {$project:{keep:{$setIntersection:["$obj1.b","$obj2.b"]},obj1:1,obj2 ...
-
根据您的MongoDB版本,总是存在某种程度的锁定,可能是收集或数据库级别较旧,甚至可能是WiredTiger存储引擎的文档级别。 然而, $out在写入$out会产生收益,因此各个文档都是从管道输出的,而不是一个一个地发送,因此每个更新对于每个文档都是原子的。 即使是mapReduce命令也有这个选项 ,您可以在其中设置“nonAtomic”作为mapReduce的输出集合呈现相同行为的条件。 使用$out时需要注意的一件事情是,当使用“替换”模式时,该阶段将执行从集合中删除所有文档(而不是替换任何现有索 ...
-
聚合管道的“out”阶段是否保持有序集合?(Does the “out” stage of the aggregation pipeline keeps an ordered collection?)[2022-04-01]
由于$out会将文档发送到存储引擎,因此MMAP存储引擎可以使用填充以允许自然文档增长,因此可能会与文档/ bson对象大小相关联。 从汇总中删除$ out并添加此代码段将显示文档大小(您可以添加任何其他字段以获取更多诊断数据)。 当我们遇到文档适合两个其他文档之间的差距的情况时,它将被添加到那里 - 所以订单将被改变 - >这意味着$ out将保持服务器顺序,但是存储引擎可以为此添加噪声。 db.coll.aggregate([pipeline]).forEach(function(doc) { ... -
你有这个信息,但你在$group阶段切断它。 只需将舞台改为以下(注意最后一个参数): { $group : { _id : "$_id.purpose", unit : { $first : "$_id.number" }, visits : { $first : "$count" } }} The following outputs what I needed : units.aggregate([ {$match:{'VisitorLogs':{$gt:[]}}}, {$ ...
-
您使用$ concat作为聚合管道中的管道阶段。 请参阅此处以获取阶段列表。 $ concat用作字符串修饰符以连接结果。 请看这里的例子。 他们倾向于在示例中的$ project管道阶段使用$ concat将文档的两个值合并为一个。 例如: { $project: { itemDescription: { $concat: [ "$item", " - ", "$description" ] } } } 在你的情况下它可能看起来像...... { $project: { event: { $concat ...
-
MongoDB聚合管道多个组使管道变得复杂(MongoDB Aggregation Pipeline Multiple Groups Complicating Pipeline)[2022-03-22]
如果我正确理解了这个问题,那就是你要找的东西。 关键概念是您可以从多个字段构造复合_id。 db.collection.aggregate( [ {$match: {cdr3_seq_aa_len: {$gt: 3}}}, {$group: { _id: {donor: "$donor", cdr3_seq_aa: "$cdr3_seq_aa"}, donor_cdr3_seq_aa_count: {$sum: 1} ... -
如何在mongo聚合框架中的流水线阶段之后加入文档(How to join documents after a pipeline stage in mongo aggregation framwork)[2023-07-28]
引入另一个$group管道步骤,您将输入文档流按中心字段分组,在组中引入使用$sum运算符的新字段。 $sum运算将由使用$cond运算符的条件确定,该运算符评估性别表达式,并根据结果,并根据评估的逻辑返回先前的计数。 考虑下面的管道延续: db.collection.aggregate([ /* previous pipeline(s) here ... */ { "$group": { "_id": "$center", " ... -
您应该传递对象数组。 那里的每个对象都描述了一个操作($ match,$ group等)。 但是只传递一个对象的数组。 此对象包含多个字段。 这是不正确的。 所以尝试写这样的查询: db.collection('myColec').aggregate( [{ $match: /*$or:[{name:"adam"},{channel:"steve"}]*/ 'name': {$in: ['adam','ste ...
-
分片群集始终具有主分片和一个或多个辅助分片。 请知道如果数据库是分片的,那么数据库中的所有集合都将被分片 不,默认情况下,您的所有馆藏都不会被分片。 所有这些集合都完全保留在主要碎片上。 要对集合进行分片,请使用shardCollection命令 另外请确认,如果分片聚合查询将在许多服务器中运行,并快速交付结果。 在分片环境中定义集合时,一个重要的事情是分片键 。 您应该确保选择一个好的分片键,它负责跨分片分发数据。 因此,如果您选择一个好的分片键,您可以期望比非分片环境更好的性能。 如果是这样,聚合查询的 ...