有一个非常流行的问题是“std :: pair vs struct with two fields”。但是我有一个关于将first
和second
值重新分配给语义命名变量的问题。在常规情况下,我们有这样的事情:
const std::pair<const int, const int> result = processSomething();
std::cout << result.second << " of " << result.first << std::endl;
但是如果我们首先将它们分配给引用变量怎么办呢?
const std::pair<const int, const int> result = processSomething();
const int &numTotal = result.first;
const int &numSuccessful = result.second;
std::cout << numSuccessful << " of " << numTotal << std::endl;
这使我们无法撰写关于first
和second
语义的评论。这种方式有什么缺点?编译器是否会为numTotal
和numSuccessful
保留堆栈?如果在主循环中使用这种模式,性能是否会下降?
从常规变量更改为引用变量(感谢您的评论)
答案 0 :(得分:13)
我没有看到任何严重的缺点,具有有意义名称的变量可以帮助使代码更清晰。一个不错的优化编译器应该能够在简单的情况下(例如你的例子)从额外的引用中删除任何开销,但是对于类型不相同的更复杂的情况(例如,它们具有不同的const限定或需要转换),可能不会。 / p>
在某些情况下,还有另一个选项可能更清晰:您可以创建所需的变量,然后创建pair
对这些变量的引用,而不是使用结果初始化pair
,并通过参考文献分配给他们:
int numTotal;
int NumSuccessful;
std::pair<int&, int&> result(numTotal, numSuccessful);
result = processSomething();
或者同样的事情,没有引用对的命名变量:
int numTotal;
int NumSuccessful;
std::pair<int&, int&>(numTotal, numSuccessful) = processSomething();
或在C ++ 11中,您可以使用标准tie
函数:
int numTotal;
int NumSuccessful;
std::tie(numTotal, numSuccessful) = processSomething();
更不寻常的解决方案不涉及临时对象,并允许您通过使用具有有意义成员名称的本地类型来创建变量const
:
struct Num {
Num(std::pair<const int, const int> p) : total(p.first), successful(p.second) { }
int total;
int sucessful;
};
const Num num = processSomething();
std::cout << num.successful << '/' << num.total << '\n';