std :: pair分配语义命名变量的第一个和第二个

时间:2014-02-07 10:50:56

标签: c++ reference std-pair

有一个非常流行的问题是“std :: pair vs struct with two fields”。但是我有一个关于将firstsecond值重新分配给语义命名变量的问题。在常规情况下,我们有这样的事情:

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;

这使我们无法撰写关于firstsecond语义的评论。这种方式有什么缺点?编译器是否会为numTotalnumSuccessful保留堆栈?如果在主循环中使用这种模式,性能是否会下降?

修复

从常规变量更改为引用变量(感谢您的评论)

1 个答案:

答案 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';