首页 > 编程语言 >c++ 模版元编程-00

c++ 模版元编程-00

时间:2023-05-29 16:13:56浏览次数:35  
标签:00 const 模版 c++ wrapper template foo class

本系列文章从零开始介绍C++模版元编程,需要有C++基础。

函数模版

template <typename T>
T add(T const a, T const b) {
  return a + b;
}

auto a = add(42, 21);
auto d = add<double>(41.0, 21); // 无法自动推导类型的时候可以显示的指定类型

类模版

template <typename T>
class wrapper {
public:
	wrapper(T const v) : value(v) {}
  T const& get() const { return value; }
private:
  T value;
};

wrapper a(1); // 模版参数推导
wrapper<int> b(2);

成员函数模版

模版类的成员函数

template <typename T>
class comoosition {
public:
  T add(T const a, T const b) {
    return a + b;
  }
};
composition<int> c;
c.add(12,32);

非模版类的成员函数模版

class compotion {
public:
  template <typename T>
  T add(T const a, T const b) {
    return a + b;
  }
};
compostion c;
c.add<int>(12,13);
c.add(1,2);

类模版的成员函数模版

template <typename T>
class wrapper {
pbulic:
  wrapper(T const v) : value(v) {}
  T const& get() const { return value; }
  
  template <typename U>
  U as() const {
    return static_cast<U>(value);
  }
private:
  T value;
};

// 成员函数模板的模板形参必须与类模板的模板形参不同

wrapper<double> a(42.1);
auto d = a.get();
auto b = a.as<int>();

模版参数

类型模版参数

template <typename T> // 不带默认参数
class wrapper {};

template <typename T = int> // 带默认参数
class wrapper {};

template <typename... T> // 可变参数模版
class wrapper {};

非类型模版

template <int V>
class foo {};

template <int V = 42>
class foo {};

template <int... V>
class foo {};
template <typename T, size_t S>
class buffer {
  T data_[S];
public:
  constexpr T const * data() const { return data_; }
  constexpr T& operator[](size_t const index) {
    return data_[index];
  }
  constexpr T const& operator[] (size_t const index) const {
    return data_[index];
  }
};

buffer<int, 10> b1; 
buffer<int, 2*5> b2;

看一种更常见的类型

struct device {
  virtual void output() = 0;
  virtual ~device() {}
};

template <void (*action) ()>
struct smart_device : device {
  void output() override {
    (*action) ();
  }
};

void say_hello_in_english() {
  std::cout << "Hello, world!\n";
}
auto w1 = std::make_unique<smart_device<&say_hello_in_english>>();
w1->output();

双重模版参数

template <typename T> 
class simple_wrapper {
public:
	T value; 
};

template <typename T> 
class fancy_wrapper {
public:
	fancy_wrapper(T const v) :value(v) {}
  
	T const& get() const { return value; }
  
	template <typename U> U as() const {
		return static_cast<U>(value); 
  }
  
private: 
  T value;
};

template <typename T, typename U, template<typename> typename W = fancy_wrapper>
class wrapping_pair {
public:
	wrapping_pair(T const a, U const b) : item1(a), item2(b) { }
	W<T> item1;
  W<U> item2;
};

默认模版参数

template <typename T = int> 
class foo { /*...*/ };

template <typename T = int, typename U = double> 
class bar { /*...*/ };
template <typename T = int, typename U> 
class bar { }; // error, 类模版带默认参数的参数,后面不能跟不带默认参数的参数。
template <typename T = int, typename U> 
void func() {} // OK
template <typename T = int> 
struct foo;

template <typename T = int> // error redefinition // of default parameter
struct foo {};

模版实例化

模版实例化可以是显式的也可以是隐式的。

隐式实例化

template <typename T>
struct foo {
  void f() {}
};

int main() {
 	foo<int> *x; // 不会实例化
  foo<int> p;  // 会
  foo<int> p1; // 会
  foo<double> *q; // 不会
	return 0;
}
template <typename T>
struct foo {
  static T data;
};

template <typename T> T foo<T>::data = 0;
int main() {
  foo<int> a;
  foo<double> b;
  foo<double> c;
  std::cout << a.data << '\n'; // 0 
  std::cout << b.data << '\n'; // 0 
  std::cout << c.data << '\n'; // 0
  
  b.data = 42;
  
  std::cout << a.data << '\n'; // 0 
  std::cout << b.data << '\n'; // 42 
  std::cout << c.data << '\n'; // 42
}

显示实例化

显示实例化分为显示实例化定义和显示实例化声明。

// 类模版
template class-key template-name <argument-list>

// 函数模版
template return-type name<argument-list> (parameter-list);
template return-type name(parameter-list);
namespace ns {
  template <typename T>
  struct wrapper {
    T value;
  };
  template struct wrapper<int>; // 显示实例化
}
template struct ns::wrapper<double>; // 显示实例化

int main() {
  
}

namespace ns {
  template <typename T>
  T add(T const a, T const b) {
    return a + b;
  }
  
  template int add(int, int);
}
template double ns::add(double, double);

标签:00,const,模版,c++,wrapper,template,foo,class
From: https://www.cnblogs.com/Heoric/p/17440697.html

相关文章

  • C++-条件变量/互斥锁/lock_guard
    条件变量参考C++Reference对于条件变量的解释和例程:https://en.cppreference.com/w/cpp/thread/condition_variable条件变量和互斥锁一般结合使用。因为线程处于等待状态中,一般需要查看一个全局变量或共享的变量的状态,来决定是否停止等待继续运行程序。对于此全局变量,必须要......
  • 1、初认 AS400
    一、AS400简介AS/400是一种主机型计算机,是IBM公司开发的。AS/400是IBM的应用服务器产品,针对企业级应用开发、重要应用系统支持进行设计开发。AS/400的系统工作环境中同时支持多种操作系统和多种编程语言的应用程序开发和运行,支持多用户环境下的数据共享、事务处理和并发控制......
  • 【2023 · CANN训练营第一季】基于Atlas 200I DK A2的智能小车结构设计和控制原理
    基于Atlas200IDKA2的智能小车结构设计和控制原理一、结构设计基本原则从零开始设计并搭建智能小车,在满足外观要求的基础上,要满足小车运转过程中的运动干涉率为0,并且需要考虑实际安装时的易用性与可行性,以及智能小车的重心位置的控制等。主要模块前中后外壳结构支撑模块。TT减速......
  • 【2023 · CANN训练营第一季】基于Atlas 200I DK A2的智能小车功能实现
    基于Atlas200IDKA2的智能小车功能实现一、地图绘制小车的行驶依赖于模型的训练,因此需要设计一张地图,用于小车行驶的模型训练过程和推理结果验证。开发者可以根据需要使用PhotoShop软件绘制不同的图层,使用可以使小车正常转弯和停车的尺寸,得到场景地图并打印。二、手动控制小车烧......
  • 遥控器、电子秤等包含纽扣电池商品应该如何办理16CFR1700.15和16CFR1700.20/ANSI C18.
    本政策适用的纽扣电池和硬币电池本政策适用于独立式纽扣电池或硬币电池,它们是扁圆形的单体电池,直径通常为5到25毫米,高度为1到6毫米。纽扣电池和硬币电池可作为单独的电池出售,但也用于各种消费品和家居用品中,其中包括遥控器、钟表、电脑、照相机、计算器、手电筒、无焰蜡烛......
  • 代码随想录算法训练营第二十天|654. 最大二叉树、617. 合并二叉树、700. 二叉搜索树
    【参考链接】654.最大二叉树【注意】1.构造二叉树,都需要用前序遍历。2.二叉树的根是数组中的最大元素。3.没必要构造新数组,通过下标控制左右区间。运行效率会高很多。【代码】1#Definitionforabinarytreenode.2#classTreeNode(object):3#def__init......
  • C++头文件理解
    看了下公司内部对于头文件的使用,感觉挺乱的。对于头文件容易搞混淆的点在于:涉及多文件,多次包含的时候容易搞错比如上面CPP就有三四个文件,每一个CPP都要按照先包含config,后包含common的顺序,在编译的时候指明。但是include头文件本质上就是:在编译时把指定的文件,包含到调用的地方......
  • 【重学C++】05 | 说透右值引用、移动语义、完美转发(下)
    文章首发【重学C++】05|说透右值引用、移动语义、完美转发(下)引言大家好,我是只讲技术干货的会玩code,今天是【重学C++】的第五讲,在第四讲《【重学C++】04|说透右值引用、移动语义、完美转发(上)》中,我们解释了右值和右值引用的相关概念,并介绍了C++的移动语义以及如何通过右值引......
  • 500行代码手写docker-实现硬件资源限制cgroups
    (5)500行代码手写docker-实现硬件资源限制cgroups本系列教程主要是为了弄清楚容器化的原理,纸上得来终觉浅,绝知此事要躬行,理论始终不及动手实践来的深刻,所以这个系列会用go语言实现一个类似docker的容器化功能,最终能够容器化的运行一个进程。本章的源码已经上传到github,地址如......
  • C++“高级程序设计实践(C++)”课程设计任务书[2023-05-28]
    C++“高级程序设计实践(C++)”课程设计任务书[2023-05-28]“高级程序设计实践(C++)”课程设计任务书一.课程设计的目的与任务本设计是课程——《面向对象编程(C++)》的一个关键实践环节。它是根据教学计划的要求,在教师的指导下,对学生实施程序设计训练的必要过程,是对前期课堂学习内......