【发布时间】:2016-07-19 07:06:52
【问题描述】:
我的任务是在 C++ 类库中迁移错误处理的概念。以前简单返回 bool(成功/失败)的方法应修改为返回 Result 对象,该对象传达机器可读的错误代码和人类可读的解释(还有一些在这里无关紧要)。
遍历数千行代码很容易出错,因此我尝试从编译器获得最好的支持来完成这项任务。
我的结果类具有 - 除其他成员方法外 - 一个构造函数,用于从代码构造结果和代码的赋值运算符:
class Result
{
public:
typedef unsigned long ResultCode;
explicit Result(ResultCode code); // (1)
Result& operator=(ResultCode code); // (2)
};
备注:我通常会为ResultCode 使用枚举类,这可以解决我的问题,但这不是一个选项。这是因为主要的设计目标是在不同的库中使用Result,每个库都应定义自己的一组结果代码,而不需要一个为所有库定义所有可能结果代码的大头文件。实际上,每个类都应该能够定义本地结果代码,以便可以从类头中获得可能的结果代码列表。因此代码不能在Result 中枚举,它们必须由使用Result 类的类定义。
为了避免隐式转换
return true;
客户端代码中的语句,构造函数已被显式声明。但是在嵌套方法调用中,又出现了一个问题。说,我有一个方法
bool doSomething()
{
return true;
}
我在返回Result 对象的函数中使用它。我想转发嵌套调用的结果代码
Result doSomethingElse
{
Result result = doSomething();
return result;
}
使用Result 的赋值运算符的当前实现,这不会给我一个编译器错误 - doSomething() 的布尔返回值被隐式转换为 unsigned long。
正如我在 C++ 文档中所读到的,只有构造函数和转换运算符可以被显式声明。
我的问题
- 为什么赋值运算符或其他方法不允许显式? IMO 允许任何方法都是显式的也是很有意义的。
- 是否有其他解决方案可以防止赋值运算符的隐式类型转换?
【问题讨论】:
-
我知道这不是你想要的答案,但为什么不在 C++ 中使用异常机制呢?不要与语言抗争。使用它。 (不过,对于提出的问题,还要加一个)。
-
您不能声明
template<typename T> void operator=(T) = delete;并保留您拥有的那个吗?它将在正常情况下使用该方法,并尝试对所有其他类型使用已删除的方法。 -
如果我在 coliru 上尝试这个,我会得到
error: conversion from 'bool' to non-scalar type 'Result' requested,没有进一步调查。 -
@Bathsheba:我喜欢使用异常和其他 C++ 东西。但是,这些库应作为共享库提供,并且不建议跨 SL 边界抛出异常。异常在内部使用,但对于与应用程序的接口,它们应转换为结果
-
您上面的代码没有使用赋值。以上任何内容均不排除使用
enum class。你的问题是“我不想用 bbq 来做这个蛋糕。recipie 说要用 350 F 的烤箱,我不能用 bbq,因为我对蜜蜂过敏。为什么我的烤箱不工作?” .您了解这如何使回答变得棘手。我的意思是,烤箱和烧烤之间有相似之处,也许对蜜蜂过敏并不是避免使用烤箱的真正原因,也许你的烤箱真的不工作,但这个问题似乎掩盖了混淆而不是描述问题。
标签: c++