首页 > 解决方案 > C++中空结构体的使用

问题描述

在我正在阅读的一些代码中,我发现空结构的用法如下:

struct input_iterator_tag { };
struct bidirectional_iterator_tag { };
struct random_access_iterator_tag { };

所以在其余的代码中,它被用作他们所说tag dispatching的 .

我想知道空结构是否还有其他用途。

从较早的帖子中我看到:

我们在 C++ 中使用空结构的三个主要原因是:

  • 基础接口
  • 模板参数
  • 一种帮助重载决议的类型。(如果我没记错的话,标签调度)

有人可以解释一下吗?

标签: c++struct

解决方案


一种帮助重载决议的类型。(如果我没记错的话,标签调度)

当你想在某个函数上使用复杂的模板特化模式时,你不要直接尝试,而是写:

template <typename T1, typename T2, other things maybe>
int foo(T1 param1, T2 param2 and so on)
{
    using tag = put your complex stuff here, which produces an empty struct
    detail::foo_impl(tag, std::forward<T1>(param1), std::forward<T2>(param2) and so on);
}

现在,编译器不必在模板专业化的竞争选择之间做出决定,因为使用不同的标签你会得到不兼容的函数。

基础接口

struct vehicle { 
    // common members and methods,
    // including (pure) virtual ones, e.g.
    virtual std::size_t num_maximum_occupants() = 0;
    virtual ~vehicle() = default;
};

namespace mixins {
struct named { std::string name; };
struct wheeled { int num_wheels; public: rev() { }; };

}  // namespace mixins
    
struct private_sedan : public vehicle, public wheeled, named {
   // I dunno, put some car stuff here
   //
   // and also an override of `num_maximum_occupants()`
};

使基本结构完全为空可能并不常见,但如果您经常使用 mixins,这当然是可能的。你可以检查继承自vehicle(虽然我不确定我会这样做)。

模板参数

不知道这意味着什么,但冒险猜测:

template <typename T>
struct foo { };

template <typename T, typename N>
struct foo<std::array<T, N>> {
    int value = 1;
};

如果你现在foo<T>::value在一个函数中使用,它只有在很少(?)异常的情况下才会T起作用int


推荐阅读