函数模板
两个不同类型参数自动推断返回类型
自动推断返回类型
template<typename T1, typename T2> //typename是比较新的写法,老版中也可以写成class
auto max (T1 a, T2 b)
{
return b < a ? a : b;
}
decltype(true ? T1() : T2())返回一个比较通用的类型,std::decay_t萃取函数则用于去掉类似const
、&
的修饰符
#include <type_traits>
template<typename T1, typename T2, typename RT =
std::decay_t<decltype(true ? T1() : T2())>>
RT max (T1 a, T2 b)
{
return b < a ? a : b;
}
函数模板的重载
模板解析过程将优先选择非模板函数,而不是从模板实例化出来的函数。但可以加入尖括号显式调用,例如::max<>(7, 42)
。
在重载模板的时候,要尽可能少地做改动。
类模板
template<typename T>
class Stack {
private:
std::vector<T> elems; // elements
public:
void push(T const& elem); // push element
void pop(); // pop element
T const& top() const; // return top element
bool empty() const { // return whether the stack is empty
return elems.empty();
}
};
在将这个 Stack<T>
)。
不过如果在类模板内部使用 Stack
而不是 Stack<T>
,表明这个内部类的模板参数类型和模板类的参数类型相同。
以下两段代码是等价的。
template<typename T>
class Stack {
…
Stack (Stack const&); // copy constructor
Stack& operator= (Stack const&); // assignment operator
…
};
template<typename T>
class Stack {
…
Stack (Stack<T> const&); // copy constructor
Stack<T>& operator= (Stack<T> const&); // assignment operator
…
};
模板函数和模板成员函数只有在被调用的时候才会实例化。
如果一个类模板有static 成员 ,对每一个用到这个类模板的类型,相应的静态成员也只会被实例化一次。
部分地使用类模板 模板参数只需要提供那些会被用到的操作,并不需要要为模板参数提供所有被模板成员函数用到的操作。
友元 通过友元重载类模板的运算符
模板类的特例化 可以对类模板的某一个模板参数进行特化,对特定的某一种类型,我们可以进行特殊的处理。
类模板的类型推导
通过用 0 初始化这个 stack 时,模板参数 T 被推断为 int,这样就会实例化出一个 Stack
template<typename T>
class Stack {
private:
std::vector<T> elems; // elements
public:
Stack () = default;
Stack (T const& elem) // initialize stack with one element
: elems({elem}) {
}
…
};
Stack intStack = 0; // Stack<int> deduced since C++17
类模板对字符串常量的推断
template<typename T>
class Stack {
private:
std::vector<T> elems; // elements
public:
Stack () = default;
Stack (T const& elem) // 按值传递Stack (T elem)
: elems({elem}) {
}
…
};
Stack intStack = 0; // Stack<int> deduced since C++17
Stack stringStack = "bottom";
使用字符串初始化stack模板类时,有必要将构造函数声明成按值传递参数的形式,不然模板类型会识别成类似char const[7]
的形式。
按值传递时,参数类型会被萃取,模板类型为char const *
。
更好的方案是当传递一个字符串常量或者 C 类型的字符串时,应该用std::string实例化 Stack 模板类,添加以下语句:
Stack( char const*) -> Stack<std::string>;
需要注意的是,此时初始化stack是不能使用=
的方式,必须使用{}
的方式。
Stack stringStack{"bottom"}; //right
Stack stringStack = "bottom"; //error
非类型模板参数
非类型模板参数,通常它们只能是整形常量
template<int Val, typename T>
T addValue (T x)
{
return x + Val;
}
template<typename T, std::size_t Maxsize>
class Stack {
private:
std::array<T, Maxsize> elems; // elements
...
}
标签:const,c++,参数,template,类型,Stack,模板
From: https://www.cnblogs.com/chilkings/p/17201317.html