[英]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()
移动到它们自己的结构包装器( Error
、 Value
)中。
将bool F::isOk()
更改为类似以下内容:
std::variant<Error, Value> F::isOk()
然后,您不能按预期在调用isOk
之前使用Error::getError
或Value::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.