C++ 创建函数签名,返回true和false,同时在失败时提供详细信息

C++ 创建函数签名,返回true和false,同时在失败时提供详细信息,c++,return-value,C++,Return Value,这个问题的简短版本是如何实现一个既返回true又返回false的函数,同时在出现故障时提供详细信息(false) 假设我想创建一个静态函数remove(),该函数将获取一个路径作为字符串,并将其从文件系统中删除。 假设删除操作可能导致一些意外错误,我希望能够返回一个状态 第1版 static bool remove( const string& path ); 如果路径被删除,则返回true,否则返回false。 但是,如果我需要有关删除过程失败的更多详细信息,该怎么办 第2版 sta

这个问题的简短版本是如何实现一个既返回
true
又返回
false
的函数,同时在出现故障时提供详细信息(
false

假设我想创建一个静态函数
remove()
,该函数将获取一个路径作为
字符串
,并将其从文件系统中删除。
假设删除操作可能导致一些意外错误,我希望能够返回一个状态

第1版

static bool remove( const string& path );
如果路径被删除,则返回
true
,否则返回
false

但是,如果我需要有关删除过程失败的更多详细信息,该怎么办

第2版

static void remove( const string& path );
此函数现在在失败时抛出一些
异常
,基本上返回删除进程失败的原因。这要求每个调用方在调用此函数时使用
try catch
,如果您不关心结果,这可能会有点烦人和难看

我正在尝试生成一个干净的签名,该签名允许我将两个版本合并为一个版本。
remove
函数只是许多静态实用程序函数中的一个,因此我希望避免必须保留这两个版本(即使它们目前不可重写)。

建议1:

static bool remove( const string& path, bool throw_on_fail );
static EResultCode remove( const string& path );
static Result remove( const string& path );
现在,调用方可以通过传递布尔标志来替换函数的两个版本。
我不喜欢这个建议。正如我所说的
remove
函数只是许多静态实用程序函数中的一个。我认为为每个函数添加布尔参数不是一个好主意。

建议2:

static bool remove( const string& path, bool throw_on_fail );
static EResultCode remove( const string& path );
static Result remove( const string& path );
这里我们有一个
enum
作为结果。
这个更好一点,但我已经可以看到下一个
if
语句
if-remove(“f1”)
中的bug。从
remove()
获取int值4并不意味着成功

建议3:

static bool remove( const string& path, bool throw_on_fail );
static EResultCode remove( const string& path );
static Result remove( const string& path );
这里我们有一个类
Result
,它将包含布尔值和详细描述。
对我来说,这似乎是过分的

问题: 我查看了公共
c++
libraries接口&API。在那里找不到压倒性的见解


我正试图为所有这些函数设计一个通用的签名。你会走哪条路?

你可以使用类似

static bool remove( const string& path, tStatus& myStatus );

并将tStatus定义为您希望返回错误的任何类型。可以像
typedef int tStatus一样简单

您可以使用

static bool remove( const string& path, tStatus& myStatus );

并将tStatus定义为您希望返回错误的任何类型。可以像
typedef int tStatus一样简单

您还可以让函数返回bool,并在参数中传递对可能包含原因的结构的引用。像这样:

bool remove(const string& path, FailReason* fr){
  //if the FailReason is a null pointer we don't fill it
  If(fr != 0);
}

可以在fail结构中传递null,也可以让函数返回bool,在参数中传递对可能包含原因的结构的引用。像这样:

bool remove(const string& path, FailReason* fr){
  //if the FailReason is a null pointer we don't fill it
  If(fr != 0);
}

如果您有一个函数
remove()
,并且该函数的目的是从文件系统中删除内容,那么可以在fail结构中传递null,我们应该期望它在正常情况下工作

在is因某种原因无法工作的情况下(它可能会失败的原因很多),我们应该将其视为正常工作情况的例外情况

我建议:

void remove() {...}
并称之为:

try
{
   remove("/home/olduser");
}
catch(std::runtime_error& e)
{
   std::cerr << "Failed to remove: " << e.what() << '\n';
}
试试看
{
删除(“/home/olduser”);
}
捕获(标准::运行时错误&e)
{

std::cerr如果您有一个函数
remove()
,并且该函数的目的是从文件系统中删除内容,那么我们应该期望它在正常情况下工作

在is因某种原因无法工作的情况下(它可能会失败的原因很多),我们应该将其视为正常工作情况的例外情况

我建议:

void remove() {...}
并称之为:

try
{
   remove("/home/olduser");
}
catch(std::runtime_error& e)
{
   std::cerr << "Failed to remove: " << e.what() << '\n';
}
试试看
{
删除(“/home/olduser”);
}
捕获(标准::运行时错误&e)
{
std::cerr您可以使用:

static bool remove(const string& path, std::nothrow_t);
static void remove(const string& path);
您可以使用:

static bool remove(const string& path, std::nothrow_t);
static void remove(const string& path);
struct状态{
std::字符串msg;
成功;
状态():成功(真){}
状态(std::string msg_):成功(false),msg(msg_){}
显式运算符bool()常量{返回成功;}
};
静态状态常数成功;
状态func1(){return true;}
状态func2(){返回成功;}
status func3(){返回状态(“出错”);}
if(func1()){std::cout
struct status{
std::字符串msg;
成功;
状态():成功(真){}
状态(std::string msg_):成功(false),msg(msg_){}
显式运算符bool()常量{返回成功;}
};
静态状态常数成功;
状态func1(){return true;}
状态func2(){返回成功;}
status func3(){返回状态(“出错”);}

如果(func1()){std::cout我在一个例子中所做的是让函数返回一个
char
const*
,带有一个
nullptr
表示成功,以及 失败。不过,在这种情况下,函数是
extern“C”
, 所以我没有那么多的选择。在C++中,我会 可能定义一个类并返回它。该类可能有 隐式转换为
bool
,如果您愿意,但我不是 确信这是个好主意;我会有一个
成功的
函数
返回的
bool
:更加清晰

注意,即使在这种情况下,您也必须存储退货 值转换为局部变量,以便具有额外的 检测到故障后信息仍然存在;您 不能简单地写:

if ( remove( path ) ) {
    //  error
} else {
    //  success
}
但我们需要写:

Results results = remove( path );
if ( !results ) {
    //  error, do something with results.message()
} else {
    //  success
}

同样非常痛苦,几乎和一个try-catch一样痛苦。

我在一个例子中所做的是让函数返回一个
字符
const*
,带有一个
nullptr
表示成功,以及 失败。不过,在这种情况下,函数是
extern“C”