gpt4 book ai didi

c++ - 使用 lambda 和宏进行错误处理有缺点吗?

转载 作者:太空狗 更新时间:2023-10-29 23:39:20 26 4
gpt4 key购买 nike

正确测试函数返回值是基础,但它很快就会使代码困惑并难以阅读,如下面的简单示例所示:

#include <iostream>
#include <fstream>

int main(int argc, char **argv)
{
std::string filename("/usr/include/malloc.h");
std::ifstream ifs(filename.c_str());
if (!ifs.is_open())
{
std::cerr << "Failed to open file " << filename << std::endl;
return 1;
}
ifs.close();
std::cout << "Passed the first error handling" << std::endl;

filename = "/this/file/does/not/exist";
ifs.open(filename.c_str());
if (!ifs.is_open())
{
std::cerr << "Failed to open file " << filename << std::endl;
return 1;
}
return 0;
}

我想到了一种通过使用宏和 c++11 lambda 函数来减少困惑的解决方案,如下所示:

#include <iostream>
#include <fstream>

#define RETURN_IF(X,Y,Z) if ( X ) { Y ; return Z; }

auto open_file_error = [](const std::string& filename)
{
std::cerr << "Failed to open file " << filename << std::endl;
};


int main(int argc, char **argv)
{
std::string filename("/usr/include/malloc.h");
std::ifstream ifs(filename.c_str());
RETURN_IF (!ifs.is_open(), open_file_error(filename), 1 );
ifs.close();
std::cout << "Passed the first error handling" << std::endl;

filename = "/this/file/does/not/exist";
ifs.open(filename.c_str());
RETURN_IF (!ifs.is_open(), open_file_error(filename), 1 );
return 0;
}

如您所见,主函数没有那么困惑。您认为这样做有什么弊端吗?还是可以大量使用的方法?

请注意,我使用了几个宏来处理有或没有返回值的情况,用于测试与值的相等性等。

我建议下面的新版本考虑两件事:- 关于偏好使用异常而不是返回值的回答和评论;- 不再强调不是问题主题的 std::ifstream 特定错误。

#include <iostream>
#include <fstream>
#include <exception>

class OurExceptionForTheExternalLibraryFailure : public std::exception {};

#define CLEANUP_AND_THROW_IF(X,Y,Z) if ( X ) { Y ; throw Z; }

/* Return true in case of succes and false otherwise */
bool anyExternalFunction(const std::string& aString)
{
std::ifstream ifs(aString.c_str());
if (ifs.is_open())
{
ifs.close();
return true;
}
else
{
return false;
}
}

auto this_external_function_error_cleanup = [](const std::string& aString)
{
std::cerr << "The external function failed " << aString << std::endl;
// other stuff
};

int main(int argc, char **argv)
{
try
{
std::string aString = "/usr/include/malloc.h";
bool functionResult = anyExternalFunction(aString);
CLEANUP_AND_THROW_IF (!functionResult, this_external_function_error_cleanup(aString), OurExceptionForTheExternalLibraryFailure() );
std::cout << "Passed the first error handling" << std::endl;

aString = "/this/file/does/not/exist";
functionResult = anyExternalFunction(aString);
CLEANUP_AND_THROW_IF (!functionResult, this_external_function_error_cleanup(aString), OurExceptionForTheExternalLibraryFailure() );
}
catch (const OurExceptionForTheExternalLibraryFailure& e)
{
std::cerr << "Catched OurExceptionForTheExternalLibraryFailure. There was an error" << std::endl;
}
return 0;
}

您如何看待这个新版本(尽管它仍然使用宏...)?

最佳答案

好吧,如果你已经在使用 lambda,并且你不想到处都是测试代码,你总是可以做类似的事情(注意:未编译/未测试的代码,)

template <typename FileReader>
void with_file(std::string file, FileReader&& reader) {
std::ifstream in(file);
if (in) {
reader(in);
} else {
throw std::runtime_error("Failed to open file: " + file); // NOTE: I'm being lazy here
}
}

int main(...) {
with_file("foo.txt", [](auto& in) {
// do something with the stream
});
}

..但这是一个偏好问题,我喜欢异常、lambda 和小的实用函数,但有些可能不......

关于c++ - 使用 lambda 和宏进行错误处理有缺点吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36894923/

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