繁体   English   中英

c++ 在编译时检查是否调用了 function

[英]c++ check at compile time if a function is called

我将在底部解释可能的重复项。

我想知道是否可以进行编译时检查以查看 function 是否在另一个 function 之前被调用。
我的用例看起来像这样:

auto f = foo();
if(!f.isOk())
    return f.getError();

auto v = f.value();

所以在这种情况下,如果用户在调用 value 之前没有调用 isOk,我会希望得到一个编译时错误。 据我所知和搜索,这似乎是不可能的,但我想在这里问一下,以确保我没有错过任何 c++ 魔法。

仿冒品:
如何在编译时检查是否可以在编译时调用 function?
这是关于了解您的 function 是否是一个 constexpr function。我想知道一个 function 是否在另一个被调用之前被调用。

如果不实质性地改变您的设计,您不可能直接获得您想要的东西。

你可以做的是通过将它们包装在一个调用中来强制调用:

??? foo(const F& f) {
     return f.isOk() ? f.value() : f.getError();
}

然而,这只是将问题转移到选择返回类型上。 您可以返回一个std::variant或对设计进行一些更改std::optional ,但无论您做什么,都将留给调用者检查实际返回的内容。

不要假设最愚蠢的用户,也不要试图保护他们免受任何可能的错误。 相反,假设他们确实阅读了文档。

必须检查返回值是否有效是一种非常常见的模式:返回指针的函数可以返回空指针,返回迭代器的函数可以返回end迭代器。 这种情况有据可查,负责的调用者将检查返回值是否有效。

为了获得进一步的灵感,我推荐你参考std::optional ,这是对 C++ 的一个相当现代的补充,它也严重依赖于用户知道他们正在处理什么。

PS:作为一个反例,用户可能会编写这样的代码,这使得您当前的设计无法在编译时进行所需的检查:

 int n;
 std::cin >> n;
 auto f = foo();
 if(n > 10 && !f.isOk())
    return f.getError();

 auto v = f.value();

这种事情的一种策略是利用__attribute__((warn_unused_result)) (对于 GCC)或_Check_return_ (msvc)。

然后,更改foo()以返回错误条件:

SomeObj obj;
auto result = foo(obj);

这将推动调用者处理错误。 当然有明显的限制:例如, foo()不能是构造函数,调用者不能使用auto作为类型名。

确保顺序的一种方法是将临时依赖性转换为物理依赖性:

将方法F::getError()F::value()移动到它们自己的结构包装器( ErrorValue )中。

bool F::isOk()更改为类似以下内容:

  • std::variant<Error, Value> F::isOk()

然后,您不能按预期在调用isOk之前使用Error::getErrorValue::value()

auto f = foo();
auto isOk = f.isOk();
if (auto* e = std::get_if<Error>(&isOk)) // Or std::visit
    return e->getError();
auto& value = std::get<Value>(&isOk);
auto v = value.value();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM