c++ - 是否可以使用结构化绑定(bind)来分配类成员?

标签 c++ c++17

我想使用 C++ 17 结构化绑定(bind)为类成员变量赋值,如下所示:

#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();
}

但此代码无法编译并出现以下错误(使用 clang 5.0):

> clang++ structured_bindings.cpp -std=c++17 -o structured_bindings
structured_bindings.cpp:20:7: error: 'result_' in capture list does not name a variable
    [ result_, error_ ] = square_root(input);
      ^
structured_bindings.cpp:20:16: error: 'error_' in capture list does not name a variable
    [ result_, error_ ] = square_root(input);
               ^
structured_bindings.cpp:20:25: error: expected body of lambda expression
    [ result_, error_ ] = square_root(input);
                        ^
3 errors generated.

lambda 捕获似乎有些困惑。当然这会起作用:

auto[result, error] = square_root(input);
result_ = result;
error_ = error;

但我想避免使用新的局部变量。结构化绑定(bind)是否可行?

最佳答案

使用std::tie为现有对象赋值:

std::tie(result_, error_) = square_root(input);

这就是它被添加到 C++11 的原因。当然,您需要放弃使用 Result 而使用 std::tuple。哪个 IMO 更适合这种临时的“返回多个东西”场景。

结构化绑定(bind)专用于声明名称。

另一种可能更好的方法是不重新发明轮子,因为 C++1z 已经摆在桌面上了。返回一个 std::optional

auto square_root(double input) {
   return input < 0 ? std::nullopt : std::optional{std::sqrt(input)}; 
}

这具有“可能有值,也可能没有”的明确语义。


顺便说一下,无条件地调用带有负输入的 std::sqrt 是个坏主意。特别是如果您事先没有以任何特殊方式配置浮点环境。

关于c++ - 是否可以使用结构化绑定(bind)来分配类成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47924527/

相关文章:

c++ - 从 R 调用 C++ 函数并集成它时出错

c++ - 使用模板元编程构建编译时命令查找表

c++ - 二进制数据作为命令行参数

c++ - 使用 C++20 比较 std::variant 和 int <=> 不是常量表达式

c++ - 保证复制省略的行为是否取决于用户定义的复制构造函数的存在?

c++ - 卸载 DLL 后是否可以存储在 DLL 中创建的对象?

c++ - 通过向右移动对值数组进行排序

c++ - gcc 和 clang 抛出 "no matching function call"但 msvc (cl) 编译并按预期工作

c++ - `std::filesystem::path::operator/(/*args*/)` 没有按预期工作

c++ - 内联变量的多次销毁