c++ - 允许对单个值进行隐式转换

标签 c++

我有一个 Flags 类,它的行为类似于 std::bitset,它正在替换旧代码库中的位打包整数。为了强制遵守较新的类,我想禁止从 int 类型进行隐式转换。

enum class Flag : unsigned int {
  none = 0,
  A = 1,
  B = 2,
  C = 4,
  //...
};

class Flags {
public:
  Flags();
  Flags(const Flag& f);
  explicit Flags(unsigned int); // don't allow implicit
  Flags(const Flags&);

private:
  unsigned int value;
};

我想只允许来自 FlagFlags 类型的隐式构造和赋值。但是,我仍然希望一些函数调用采用 Flags 参数来接受文字 0,但不接受其他整数:

void foo(const Flags& f);

foo(Flags(0)); // ok but ugly
foo(1); // illegal because of explicit constructor
foo(0); // illegal, but I want to allow this

这可能吗?允许隐式转换 0 而不允许其他值?

最佳答案

一种方法:

添加一个接受 void* 的构造函数。

由于文字 0 可以隐式转换为 void* 空指针,而文字 1 则不能,这将提供所需的行为表明的。为了安全起见,您可以断言构造函数中的指针为空。

缺点是现在您的类可以从任何可隐式转换为 void * 的内容构造。一些意想不到的东西是可以转换的——例如在 C++11 之前,std::stringstream 可以转换为 void*,基本上是 hack 因为 explicit operator bool 还不存在。

但是,只要您意识到潜在的陷阱,这在您的项目中可能会奏效。

编辑:

其实,我想起了一个让这更安全的方法。使用指向私有(private)类型的指针代替 void*

它可能看起来像这样:

class Flags {
private:
  struct dummy {};
public:
  Flags (dummy* d) { ... }
  ...
};

文字 0 转换仍然有效,并且某些用户定义的类型无意中意外转换为 Flags::dummy * 的难度要大得多。

关于c++ - 允许对单个值进行隐式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44511003/

相关文章:

c++ - 异常多重继承

c++ - 如何将列表中的所有元素移动到数组或 vector 或其他任何内容

c++ - cudaMemCpy2D() 的堆内存上具有连续行的二维数组

c++ - 如何使用 JSON-CPP?

c++ - 为游戏开发编写 map 编辑器

c++ - 选择默认的 gcc/g++ 编译器

c++ - HEX 字符串转 UTF-8(UNICODE) 字符串

c++ - 我想要返回类型的指针,但我想让我的函数返回派生类的指针

c++ - 如何在 Linux 上执行适用于 x86、arm、GCC 和 icc 的原子操作?

c++ - 向 pthread 函数传递和访问多个参数