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

hap*_*set 5 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;
Run Code Online (Sandbox Code Playgroud)

但是如果我们首先将它们分配给引用变量呢:

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;
Run Code Online (Sandbox Code Playgroud)

这使我们免于撰写关于first和的语义的评论second.这种方式有什么缺点?编译器会为numTotal和保留堆栈numSuccessful吗?如果在主循环应用中使用此模式,性能是否会下降?

修复

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

Jon*_*ely 14

我没有看到任何严重的缺点,具有有意义名称的变量可以帮助使代码更清晰.一个不错的优化编译器应该能够在简单的情况下(例如你的例子)从额外的引用中删除任何开销,但是对于类型不相同的更复杂的情况(例如,它们具有不同的const限定或需要转换)可能不会.

在某些情况下,还有另一个选项可能更清晰:pair您可以创建所需的变量,然后创建pair对这些变量的引用,并通过引用分配给它们,而不是使用结果初始化a :

int numTotal;
int NumSuccessful;
std::pair<int&, int&> result(numTotal, numSuccessful);
result = processSomething();
Run Code Online (Sandbox Code Playgroud)

或者同样的事情,没有引用对的命名变量:

int numTotal;
int NumSuccessful;
std::pair<int&, int&>(numTotal, numSuccessful) = processSomething();
Run Code Online (Sandbox Code Playgroud)

或者在C++ 11中,您可以使用标准tie函数:

int numTotal;
int NumSuccessful;
std::tie(numTotal, numSuccessful) = processSomething();
Run Code Online (Sandbox Code Playgroud)

一个更不寻常的解决方案是不涉及临时对象,并允许您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';
Run Code Online (Sandbox Code Playgroud)