Member templates
成员模板
模板声明%28类,,,功能,和变量%28因为C++14%29%29可以出现在成员规格属于%27T的任何类、结构或联合的局部类...
二次
#include <iostream>
#include <vector>
#include <algorithm>
struct Printer { // generic functor
std::ostream& os;
Printer(std::ostream& os) : os(os) {}
template<typename T>
void operator()(const T& obj) { os << obj << ' '; } // member template
};
int main()
{
std::vector<int> v = {1,2,3};
std::for_each(v.begin(), v.end(), Printer(std::cout)
std::string s = "abc";
std::for_each(s.begin(), s.end(), Printer(std::cout)
}
二次
产出:
二次
1 2 3 a b c
二次
成员模板的部分专门化可能同时出现在类作用域和封闭命名空间范围,但显式专门化可能只出现在封闭命名空间范围。
二次
struct A {
template<class T> struct B; // primary member template
template<class T> struct B<T*> { }; // OK: partial specialization
// template<> struct B<int*> { }; // Error: full specialization
};
template<> struct A::B<int*> { }; // OK
template<class T> struct A::B<T&> { }; // OK
二次
如果封装类声明反过来是类模板,那么当在类主体之外定义成员模板时,它将接受两组模板参数:一个用于封闭类,另一个用于其本身:
二次
template<typename T1>
struct string {
// member template function
template<typename T2>
int compare(const T2&
// constructors can be templates too
template<typename T2>
string(const std::basic_string<T2>& s) { /*...*/ }
};
// out of class definition of string<T1>::compare<T2>
template<typename T1> // for the enclosing class template
template<typename T2> // for the member template
int string<T1>::compare(const T2& s) { /* ... */ }
二次
成员函数模板
析构函数和复制构造函数不能是模板。如果声明了模板构造函数,则可以使用复制构造函数,而是使用隐式声明的复制构造函数。
成员函数模板不能是虚拟的,派生类中的成员函数模板不能覆盖基类中的虚拟成员函数。
二次
class Base {
virtual void f(int
};
struct Derived : Base {
// this member template does not override B::f
template <class T> void f(T
// non-template member override can call the template:
void f(int i) override {
f<>(i
}
};
二次
可以声明具有相同名称的非模板成员函数和模板成员函数。如果冲突%28,当某些模板专门化与非模板函数签名完全匹配(%29)时,除非提供了显式模板参数列表,否则该名称和类型的使用将引用非模板成员。
二次
template<typename T>
struct A {
void f(int // non-template member
template<typename T2>
void f(T2 // member template
};
//template member definition
template<typename T>
template<typename T2>
void A<T>::f(T2)
{
// some code
}
int main()
{
A<char> ac;
ac.f('c' // calls template function A<char>::f<char>(int)
ac.f(1 // calls non-template function A<char>::f(int)
ac.f<>(1 // calls template function A<char>::f<int>(int)
}
二次
成员函数模板的类外定义必须为等价物
到类%28中的声明,请参见函数模板重载对于等效性%29的定义,否则将被视为重载。
二次
struct X {
template<class T> T good(T n
template<class T> T bad(T n
};
template<class T> struct identity { using type = T; };
// OK: equivalent declaration
template<class V>
V X::good(V n) { return n; }
// Error: not equivalent to any of the declarations inside X
template<class T>
T X::bad(typename identity<T>::type n) { return n; }
二次
转换函数模板
用户定义的转换函数可以是模板。
二次
struct A {
template<typename T>
operator T*( // conversion to pointer to any type
};
// out-of-class definition
template<typename T>
A::operator T*() {return nullptr;}
// explicit specialization for char*
template<>
A::operator char*() {return nullptr;}
// explicit instantiation
template A::operator void*(
int main() {
A a;
int* ip = a.operator int*( // explicit call to A::operator int*()
}
二次
期间过载分辨率,则找不到转换函数模板的专门化。名称查找相反,所有可见的转换函数模板都会被考虑,而每一个专门化都是由模板参数推导%28,它有转换函数模板%29的特殊规则,它的使用方式似乎是通过名称查找找到的。
在派生类中使用-声明不能引用基类中模板转换函数的专门化。
A user-defined conversion function template cannot have a deduced return type. struct S { operator auto() const { return 10; } // OK template | (since C++14) |
---|
Member variable templates A variable template declaration may appear at class scope, in which case it declares a static data member template. See variable templates for details. | (since C++14) |
---|
缺陷报告
以下行为更改缺陷报告追溯应用于先前发布的C++标准。
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 1878 | C++14 | operator auto was technically allowed | operator auto forbidden |
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。