跟我学C++中级篇—空类标签 一、空类在C中有一种特殊的类就是空类。所谓空类就是啥都没有。前面分析过空类作为基类的优势也分析过迭代器标签中空类的应用。说明空类这个东西还是很有价值的。正如数学中的零它的存在有着重要的作用。同样在C中空类在一些场景下也起了关键的作用。二、空类标签通过迭代器的标签可以进一步理解空类标签。它其实是作为类型标签来参与重载、模板特化及特定语义的处理一种机制。一般是指空的struct或class类型。即它本身未包含任何信息和数据只是一种类型的表现。如下structA_tag{};class B_tag{};它一般作为一种标签为分机制在编译阶段应用较为广泛。因为它是空的所以不会产生运行时的开销。如果对STL的源码有过较多分析可以发现在STL的源码中有很多的地方用到了这种机制。三、作用空类标签在C中的各个应用场景有着不同的作用主要有编译期分发处理可以在编译期进行类型的区分也可以作为萃取的基础实现空类型的判断重载函数的处理可以通过空类标签作为重载的区别从而支持各种自定义的重载实现零运行时成本这就与其本身的定义相关没有内容就意味着运行时的开销也没有模板特化空类标签可以通过模板参数让编译器为特定场景下的数据类型创建提供支持语义表达可以通过空标签名称的定义等机制实现正确的语义传递防止出现错误的理解标记和占位符这个就更好理解了不表达语义只为达到某种目的而占用一个空位或者通过空类标签来实现类似ID标识其主要的应用场景包括tag dispatchID标识的典型应用模板重载重载函数的应用策略选择这个类似于编译期的场景划分类型分类就是标记或萃取STL迭代器分类典型的编译期的类型处理表达构造语义如std::nullopt_t、std::in_place_t等大家如果有兴趣可以找一找其它的空类应用的场景对比分析一下。四、例程下面看一个空标签类的例程#includeiostream#includeiterator#includelist#includevectortemplatetypename ItvoiditImpl(Itit,intn,std::random_access_iterator_tag){std::coutcall random access iteratorstd::endl;itn;}templatetypename ItvoiditImpl(Itit,intn,std::bidirectional_iterator_tag){std::coutcall bidirectional iteratorstd::endl;while(n--0){it;}}templatetypename ItvoidcustomFunc(Itit,intn){//获取标签类型using Categorytypename std::iterator_traitsIt::iterator_category;//根据标签类型进行重载itImpl(it,n,Category{});}intmain(){std::vectorintv{10,22,18,36,59};std::listintl{1,10,20,66,100};autovItv.begin();autolItl.begin();customFunc(vIt,2);customFunc(lIt,2);std::coutvector cur:*vItstd::endl;std::coutlist cur:*lItstd::endl;return0;}五、总结大家可能都看过《射雕英雄传》里面一种拳叫做“空明拳”。当时觉得看到招式什么“空碗盛饭、空屋住人”觉得好笑。其实抽象来看这才是“空”的意味。空才能生物空才能状态变化。计算机中也是如此空是非空的对应是对象的一种有效标签。