【问题标题】:How avoid error on not evaluated code C++? [closed]如何避免未评估代码 C++ 的错误? [关闭]
【发布时间】:2021-04-11 06:05:58
【问题描述】:

为最模棱两可和离奇的标题道歉。
假设我们有 2 个类 A 和 B。
B 类有接口 hasSmth 但 A 类没有。
如何让这段代码在没有编译错误的情况下进行评估?

class A {
    //..implementation
    int id() { return 1; }
};

class B {
    //..implementation
    int id() { return 2; }
    bool hasSmth() { return true; }
};

int main() 
{
    auto obj = someFunction();//returns A or B
    if (obj.id() == 1 || (obj.id() == 2 && obj.hasSmth())) {
        ...
    }
}

如果函数返回 B 类型的 obj,那么我们很好。
但是如果它返回 A 类型的 obj,编译器会抱怨 A 没有 hasSmth,不管 if 从未被评估过的那部分。

有人可以提供解决方法吗?

【问题讨论】:

  • “返回 A 或 B”是不可能的。所有函数的返回类型必须在编译时已知。
  • 这看起来可能是 XY 问题的情况:xyproblem.info
  • @Someprogrammerdude 在这种情况下,它将返回std::variant ...并且问题可能可以通过visit 或其他方式解决。但是在 OP 指定 someFunction 之前无法回答这个问题
  • 我同意@jjramsey 和@MSalters,根据“类型”(您的id 确实是)选择代码路径几乎总是一种反模式。您尝试使用这样的代码解决的实际问题是什么?
  • “someFunction() 与问题无关” - 它是问题的确切根源。如果不是这样,这个问题甚至不会在这里。这以某种方式返回了两种可能不同的类型,这一事实首先使这个动物园成为了拱顶。如果我们没有完全了解您在做什么,我们就无法安排可能的解决方案

标签: c++ c++11 expression-evaluation


【解决方案1】:

有人可以提供解决方法吗?

阅读someFunction 的声明,看看它返回了什么。如果不返回B,则不要写obj.hasSmth()。问题解决了。

现在,让我们稍微改变一下问题。假设您想在不知道返回类型的情况下完成这项工作。也许是因为您实际上可能正在编写一个适用于不同类型的模板,而不是main。有几种方法,但函数重载是一种简单的方法:

bool check([[maybe_unused]] const A&) {
    return true;
}

bool check(const B& b) {
    return b.hasSmth();
}

template<bool returnsA>
void foo() {
    auto obj = someTemplate<returnsA>(); // returns A or B
    if (check(obj)) {

【讨论】:

  • OP 说该函数可以返回 AB,因此他们需要一种方法来从调用站点处理它。
  • @NathanOliver 一个函数只能返回一种类型。我添加了进一步的说明来检查它是哪种类型。
  • template &lt;int i = 0&gt; auto foo() { if constexpr (i == 0) return 0; else return 0.0; } 可以返回两种不同的类型。
  • @NathanOliver 从技术上讲,这不是一个函数。那是一个函数模板。 auto obj = foo(); 将调用该模板的特定实例,该实例总是返回 int
  • @EduardRostomyan 您可以有一个通用模板接受其中一个系列,并仅为另一个(较小)系列中的那些指定显式重载。避免为这两个系列的所有类指定重载的一种方法是使用 SFINAE 魔术,但这很复杂。有了 C++20 的概念,它可能会变得更好。
猜你喜欢
  • 1970-01-01
  • 2021-05-03
  • 2010-10-03
  • 2011-09-17
  • 2011-05-19
  • 2010-12-22
  • 2012-07-09
  • 2014-06-13
  • 2011-04-03
相关资源
最近更新 更多