gpt4 book ai didi

c++ - 有没有一种简单的方法来检查C++中的不安全表达式?

转载 作者:行者123 更新时间:2023-12-01 14:44:19 26 4
gpt4 key购买 nike

我试图找到一种[更好]的方式来运行/检查可能不安全的表达式或以更优雅的方式执行多个null检查。

这是我要改进的代码示例:

if (myObjectPointer &&
myObjectPointer->getSubObject() &&
myObjectPointer->getSubObject()->getSubSubObject() &&
myObjectPointer->getSubObject()->getSubSubObject()->getTarget()) {

// Use safely target
... *(myObjectPointer->getSubObject()->getSubSubObject()->getTarget()) ...
}

我试图找到一种更优雅的方法来实现此目的(而不是上面的详细null检查)。这是我的第一个想法:
template<typename T>
bool isSafe(T && function) {
try {
function();
// Just running the func above, but we could e.g. think about returning the actual value instead of true/fase - not that important.
return true;
}
catch (...) {
return false;
}
}

...
// And use the above as follow :
if(isSafe([&](){ myObjectPointer->getSubObject()->getSubSubObject()->getTarget(); })) {
// Use safely target
}
...

上面的问题是我们无法捕获信号(分段故障,...)。而且我显然不想处理程序中的所有信号,而只希望处理这个非常具体的check / eval函数。

我是用错误的方式解决问题吗?还有其他建议吗?还是冗长的if是否不可避免?

提前谢谢了。

最佳答案

我在想这个,就像Jarod42所说的,一定有一些可变参数的模板。我不是最擅长的,但是想出了这个:

#include <memory>
#include <functional>
#include <iostream>

template <typename T, typename MemFn, typename... Params>
void safeExecute(T* ptr, MemFn memFn, Params&&... params) {
if (ptr != nullptr)
safeExecute(std::invoke(memFn, ptr), std::forward<Params>(params)...);
}

template <typename T, typename MemFn>
void safeExecute(T* ptr, MemFn memFn) {
if (ptr != nullptr) std::invoke(memFn, ptr);
}


struct Target {
void Bar() { std::cout << "tada!\n"; };
};


template<typename T>
class Object {
private:
std::unique_ptr<T> ptr;
public:
Object() : ptr(std::make_unique<T>()) {}

T* Get() { return ptr.get(); }
};

using SubSubObject = Object<Target>;
using SubObject = Object<SubSubObject>;
using MyObject = Object<SubObject>;

int main() {
auto myObjectPtr = std::make_unique<MyObject>();

safeExecute(myObjectPtr.get(),
&MyObject::Get,
&SubObject::Get,
&SubSubObject::Get,
&Target::Bar);
}

编辑:
我一直在考虑使用更通用的返回类型的想法,因此我尝试了不调用成员函数,而是返回指向对象的std::optional指针的选项。这使我进入以下代码:
#include <memory>
#include <functional>
#include <iostream>
#include <optional>

template <typename T, typename MemFn, typename... Params>
auto safeGetObject(T* ptr, MemFn memFn, Params&&... params)
-> decltype(safeGetObject(std::invoke(memFn, std::declval<T>()), std::forward<Params>(params)...))
{
if (ptr != nullptr) return safeGetObject(std::invoke(memFn, ptr), std::forward<Params>(params)...);
return {};
}

template <typename T, typename MemFn>
auto safeGetObject(T* ptr, MemFn memFn) -> std::optional<decltype(std::invoke(memFn, std::declval<T>()))> {
if (ptr != nullptr) return std::invoke(memFn, ptr);
return {};
}

struct Target {
int Bar(int a, int b) const noexcept {
return a+b;
};
};

template<typename T>
class Object {
private:
std::unique_ptr<T> ptr;
public:
Object() noexcept : ptr(std::make_unique<T>()) {}

T* Get() const noexcept { return ptr.get(); }
};

using SubSubObject = Object<Target>;
using SubObject = Object<SubSubObject>;
using MyObject = Object<SubObject>;

int main() {
auto myObjectPtr = std::make_unique<MyObject>();

auto optionalTarget = safeGetObject(
myObjectPtr.get(),
&MyObject::Get,
&SubObject::Get,
&SubSubObject::Get);

auto result = optionalTarget ? optionalTarget.value()->Bar(3, 4) : -1;
std::cout << " result " << result << '\n';
}

关于c++ - 有没有一种简单的方法来检查C++中的不安全表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58598168/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com