【问题标题】:Can I conditionally choose which variable to assign to?我可以有条件地选择分配给哪个变量吗?
【发布时间】:2015-12-11 01:25:42
【问题描述】:

this question 基本相同,但用于 C++。

最简单的方法是:

if (condition) {
    a = f(x);
} else {
    b = f(x);
}

虽然这满足了我的需要,但一直困扰着我的是我不得不重复输入 f(x) 两次,更不用说在只执行一行时将代码扩展到这么多行。如果我有更多的目标变量可供选择怎么办?

switch(condition variable) {
case 1:
    var1 = f(x);
    break;
case 2:
    var2 = f(x);
    break;
...
case y:
    vary = f(x);
    break;
}

这对我来说看起来很不雅。

C++ 中有什么东西可以让我做以下事情吗?

do-something-that-returns-a-lvalue = f(x);

如果它不被称为左值,请原谅我,我对 C++ 还是比较陌生。但是你们知道我的意思 - 要为其赋值的目标变量。

【问题讨论】:

  • 您当然可以编写一个返回引用并分配给它的函数。
  • 我该怎么做?函数的返回类型应该是什么样的?
  • 虽然这不是问题的直接答案,但fval = f(x); if (condition) a = fval; else b = fval 对我来说更易读,同时仍然是干燥的。
  • @Amadan 我理解 DRY 原则,但它一直困扰着我,即使我这样做了,fval 对我来说仍然是一种重复形式。这就是我称之为不优雅的原因——它似乎是一个解决方案,但实际上并非如此。
  • 这让我觉得新手使用编号变量而不是数组。如果你有T vars[size],那么vars[condition_variable] = f(x)。当然你最好用std::vectorstd::array

标签: c++ variable-assignment


【解决方案1】:

您可以形成一个引用或指向要分配的变量的指针。

(condition ? a : b) = f(x);  // reference

以上版本是aschepler在评论中建议的。

*(condition ? &a : &b) = f(x);  // pointer

参考版本基本上等同于下面使用辅助函数的更详细的示例。

template <typename T>
T&
conditional_reference(bool pred, T& yes, T& no) noexcept
{
  return pred ? yes : no;
}

// And then later

conditional_reference(condition, a, b) = f(x);

我的观点是,就代码清晰度而言,您传统的 if 然后 else 控制流可能仍然是最佳选择。

如果赋值的来源是一个比f(x) 更复杂的表达式,您可以将其结果存储在一个临时变量中,然后只在条件中分配该变量。 C++11 移动语义使得在许多情况下可以使用此类临时对象。

【讨论】:

  • 如果ab 具有相同的类型,那么普通的旧(condition ? a : b) = f(x); 就可以了。
  • @aschepler 老实说,我有点惊讶这行得通,但仔细想想,确实如此。我会记住的。
  • 这很可能是我正在寻找的确切解决方案。谢谢!我会接受这个作为答案。
  • @thegreatjedi 所以您实际上并没有寻找两个以上的变量?
  • 当然,您可以将模式扩展到两个以上的变量((y == 1) ? a : (y == 2) ? b : c) = f(x),但它不会很好地扩展。
【解决方案2】:

如果您可以在编译时决定分配给哪个变量,那么您就可以摆脱这种非常干净且零开销的方法:

std::get<constexpr_indexer()>(std::tie(var1, var2, var3, var4)) = f(x);

std::get, std::tie

【讨论】:

  • 感谢您的回答!我认为这一点尤其值得了解,尽管不幸的是它仅限于编译时间。太糟糕了,我不能选择多个答案。
【解决方案3】:

您可以在 switch 语句中分配一个指针变量(例如 double * p)。

switch(condition variable) {
case 1:
    p = & var1;
    break;
case 2:
    p = & var2;
    break;
...
case y:
    p = & vary;
    break;
}

那么你就可以在你switch语句之后做这个了。

*p = f(x);

【讨论】:

  • 这并不能真正解决问题。现在我必须使用左侧的指针变量来执行 switch 语句。本质上是一样的。我的问题是是否可以避免 switch 语句,并将相同的功能合并到一行或类似的东西中。
  • @thegreatjedi 您可以按照 5gon12eder 的建议使用三元运算符。但是如果超过这两个条件,代码就会变得不可读。
【解决方案4】:

就像您链接到的问题一样,您仍然有一个XY problem。你为什么需要这个?为什么你觉得编写更多可能不可读和不可维护的代码不如简单的 if/else 条件优雅?但问题的核心是,在什么有效的场景下,你会有 26 个(按照字母表)具有相同值的变量?

除非您有类似于原始问题(二叉搜索树)的场景,否则只使用一个变量。

请阅读DRY unrelated, but nearly identical, code:

你不做 DRY 不是因为有人在某本书的某个地方写了它是好事,你做 DRY 是因为它实际上有实实在在的好处。

【讨论】:

  • @Downvoters 看到答案的可变性,除了避免“干”之外,没有明确说明 OP 实际想要什么,这强烈表明“不清楚你在问什么”或“太宽泛"。
  • 如果您认为某个问题“过于宽泛”或“不清楚您在问什么”,建议的程序是要求缩小或澄清问题,如果这不起作用,将其标记为关闭。因此,发布宽泛或不明确的答案不是借口。也就是说,我觉得你的回答不值得投反对票。
  • 我遇到了跨不同程序的实例,我想要做的就是“选择要分配给哪个变量”。我知道有多种方法可以选择使用哪个变量的值,所以我很自然地好奇,反之亦然,因为我经常遇到对它的需求。对我来说,当不同的情况有显着不同的代码时,应该使用类似 switch-case 语句的东西,而不是重复一个语句 n 次。我不是要在此时此地解决一个问题,而是要了解我可以使用哪些技术。
猜你喜欢
  • 2019-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-13
  • 2021-12-28
  • 1970-01-01
  • 2015-11-09
  • 1970-01-01
相关资源
最近更新 更多