【发布时间】:2016-12-08 18:43:39
【问题描述】:
让我们考虑下一段代码:
struct Channel; // somewhere declared
using iter_t = std::set<Channel>::iterator;
std::set<Channel> myset;
std::pair<iter_t, bool> emplaced = myset.emplace(arg1,arg2);
然后emplaced.first 包含元素的迭代器,emplaced.second 表示元素是否已添加或已存在。 first 和 second 对我来说还不清楚。我想重命名这些字段:
struct ChannelAddedResult
{
iter_t channelIter;
bool wasAdded;
public: // --- Functions, constructors ---
ChannelAddedResult(std::pair<iter_t, bool> &&pa) {
this->channel = pa.first;
this->added = pa.second;
}
};
此构造函数复制值。右值引用没有任何好处。对吧?
但是如何将std::pair<iter_t, bool> 转换为ChannelAddedResult?这种类型是等价的。所以C风格的对话可能看起来像:
union CarUni {
std::pair<iter_t, bool> pair;
ChannelAddedResult car;
}
// Use
CarUni u;
u.pair = myset.emplace(arg1,arg2);
auto ch = *u.car.channelIter;
bool a = u.car.wasAdded;
这允许在没有额外副本的情况下实现重命名。可能是 C-casting (ChannelAddedResult)emplaced_pair 会做同样的工作,但它在 C++ 中已被弃用。从类型安全的角度来看,这两种转换是危险的。
这种转换有 C++11 方式吗?
【问题讨论】:
-
您所说的“C 风格对话”在哪里?这就是C++。 C 风格的转换(在您的示例中 未使用)在 C++ 中不被弃用。总体而言,您的代码看起来不错,并且绝不“从类型安全的角度来看是危险的”。您到底关心什么?
-
std::pair<iter_t, bool> &emplaced == myset.emplace(arg1,arg2);应该是std::pair<iter_t, bool> &emplaced = myset.emplace(arg1,arg2); -
std::pair<iter_t, bool> &emplaced == myset.emplace(arg1,arg2);请避免发布因与您的问题无关的原因而无法编译的代码。我猜有两个错别字,但是......如果有错别字,那么您的代码中有多少其他随机功能是您不打算的错别字? -
第二,你认为复制一个标准集迭代器和一个布尔值有多贵?您认为优化有多难?
-
昂贵 - 这里 2 份不计。但这只是sn-p。在一些更扩展的代码中,即放置 100000000000 个通道可能会减慢应用程序的速度。这个例子实现了重命名字段的想法。我可以想象其他的实现和变化。
标签: c++ c++11 rvalue-reference