编辑代码

#include <iostream>

// 标记类型
struct BigArrayTag {};
struct NormalPointerTag {};

// 默认的大数组分配器,只是为了演示
struct DefaultBigArrayAllocator {};

// 模拟大数组的模板
template <class T, class Allocator>
class BigArrayTemp {
public:
  typedef BigArrayTag ArrayTag; // BigArrayTemp将使用BigArrayTag

  // BigArray的模拟创建
  void create(size_t size) {
    std::cout << "BigArrayTemp create called with size: " << size << std::endl;
  }
};
/**
 * 是一个通用模板,它定义了一个 typedef,通过 typename Array::ArrayTag 来提取 Array 类型中嵌入的 ArrayTag 类型。
 * 这意味着这个通用版本的 ArrayTraits 期望处理的 Array 类型中已经定义了一个名为 ArrayTag 的类型别名。
*/
template <class Array>
struct ArrayTraits {
  typedef typename Array::ArrayTag ArrayTag;  //类型萃取技术
};
///===========================================以下这俩都是针对typedef NormalPointerTag ArrayTag;
//---如果通过模板参数--中的特化,模板参数满足 Array * 指针,就会获取到:typedef NormalPointerTag ArrayTag;
template <class Array>
struct ArrayTraits<Array *> {
  typedef NormalPointerTag ArrayTag;
};
//---如果通过模板参数--中的特化,模板参数满足 const Array* 指针,慧慧获取到:typedef NormalPointerTag ArrayTag;
template <class Array>
struct ArrayTraits<const Array *> {
  typedef NormalPointerTag ArrayTag;
};
// 大数组的封装  
template <class T>
class BigArray : public BigArrayTemp<T, DefaultBigArrayAllocator> {};

// 构造函数模板
template <class Array>
void construct(Array &array) {
  do_construct(array, typename ArrayTraits<Array>::ArrayTag());
}

// do_construct重载 - 大数组版本
template <class Array>
void do_construct(Array &array, BigArrayTag) {
    std::cout<<"do_construct-大数组版本"<<std::endl;
  //UNUSED(array);
}

// do_construct重载 - 普通指针版本
template <class Array>
void do_construct(Array &array, NormalPointerTag) {
  array = nullptr;
    std::cout<<"do_construct-普通指针版本"<<std::endl;
}

// 宏来忽略未使用的参数
#define UNUSED(x) (void)(x)

// 演示代码
int main() {
  BigArray<int> big_array; // BigArray类型
  int *normal_ptr = nullptr; // 普通指针类型
  const int *const_normal_ptr = nullptr; // const指针类型

  construct(big_array); // 应该调用BigArrayTag版本的do_construct
  construct(normal_ptr); // 应该调用NormalPointerTag版本的do_construct
  construct(const_normal_ptr); // 应该调用NormalPointerTag版本的do_construct

  return 0;
}