可以使用结构化绑定来分配类成员吗? 我想使用C++ 17结构化绑定来为类成员变量赋值,比如: #include <cmath> #include <iostream> struct Result { double value; bool error; }; Result square_root(double input) { return {std::sqrt(input), input < 0}; } struct Calculator { double result_; bool error_; public: void ComputeSquareRoot(double input) { [ result_, error_ ] = square_root(input); } void DisplayResult() { if (error_) std::cout << "Cannot take the square root of a negative number.\n"; else std::cout << "The square root is " << result_ << ".\n"; } }; int main(int argc, char* argv[]) { Calculator calc; calc.ComputeSquareRoot(64); calc.DisplayResult(); }
似乎对lambda capture有些混淆。这当然会奏效:可以使用结构化绑定来分配类成员吗? 我想使用C++ 17结构化绑定来为类成员变量赋值,比如: #include <cmath> #include <iostream> struct Result { double value; bool error; }; Result square_root(double input) { return {std::sqrt(input), input < 0}; } struct Calculator { double result_; bool error_; public: void ComputeSquareRoot(double input) { [ result_, error_ ] = square_root(input); } void DisplayResult() { if (error_) std::cout << "Cannot take the square root of a negative number.\n"; else std::cout << "The square root is " << result_ << ".\n"; } }; int main(int argc, char* argv[]) { Calculator calc; calc.ComputeSquareRoot(64); calc.DisplayResult(); },c++,c++17,C++,C++17,似乎对lambda capture有些混淆。这当然会奏效: auto[result, error] = square_root(input); result_ = result; error_ = error; 但是我想避免使用新的局部变量。结构化绑定是否可以这样做?用于为现有对象赋值: std::tie(result_, error_) = square_root(input); 这就是为什么它被添加到C++11中。当然,您需要放弃使用Result,转而使用std::tuple。哪种IMO
auto[result, error] = square_root(input);
result_ = result;
error_ = error;
但是我想避免使用新的局部变量。结构化绑定是否可以这样做?用于为现有对象赋值:
std::tie(result_, error_) = square_root(input);
这就是为什么它被添加到C++11中。当然,您需要放弃使用Result
,转而使用std::tuple
。哪种IMO更适合这种特殊的“返回多个东西”场景
结构化绑定专门用于声明新名称
另一种可能更好的方法是不重新发明轮子,因为C++1z已经上市。返回一个std::可选的
auto square_root(double input) {
return input < 0 ? std::nullopt : std::optional{std::sqrt(input)};
}
自动平方根(双输入){
返回输入<0?std::nullopt:std::可选{std::sqrt(输入)};
}
这具有明确的语义“可能有值,也可能没有值”
顺便说一下,使用负输入无条件调用std::sqrt
是个坏主意。尤其是如果您之前没有以任何特殊方式配置浮点环境。我想您可以在计算器中放置结果对象,而不是单独的变量。@Galik是的,这是一个有点做作的示例来演示这个问题。:)在这种情况下,我个人并不喜欢std::tuple
,因为我更喜欢命名值而不是get
或get
,尽管std:tie
看起来不太糟糕。我认为std::optional
比两者都好——我会试试看。谢谢@Josh Peterson-我确实明白你关于std::tuple
的观点。我通常会通过添加enum{value,error}
来缓解它。因此,这个调用看起来像是std::get(…)
“结构化绑定专门用于声明*新*对象。”这可能是一个快速解释它的方法,但在我看来,这是非常不准确的,而且它只会在用户遇到他们不期望的事情时导致进一步的混乱,因为他们对结构化绑定的想法是错误的。SBs引入的是现有对象的成员(或get()
调用等)的新名称。在本例中,该对象是平方根()
的新的、不可见的、必然是生命周期延长的结果,但它也可能是在当前语句之前已经存在的结构。@下划线\u-确定。名称将比对象更容易伪造它。
auto square_root(double input) {
return input < 0 ? std::nullopt : std::optional{std::sqrt(input)};
}