C++2.0——語言新特性之Variadic Templates
variadic template 特性本身是一個很自然的需求,它完善了 C++ 的模板設計手段。原來的模板引數可以使類和函式的引數型別“任意化”,如果再加上“引數個數的任意化”,那麼在引數方面的設計手段就基本上齊備了,有了variadic template 顯然可以讓設計出來的函式或是類有更大的複用性。因為有很多處理都是與“處理物件的個數”關係不大的,比如說打屏(printf),比如說比較大小(max,min),比如函式繫結子(bind,function要對應各種可能的函式就要能“任意”引數個數和型別)。如果不能對應任意個引數,那麼就總會有人無法重用已有的實現,而不得不再重複地寫一個自己需要的處理,而共通庫的實現者為了儘可能地讓自己寫的類(函式)能複用在更多的場景,也不得不重複地寫很多的程式碼或是用詭異的技巧,巨集之類的去實現有限個“任意引數”的對應。
語法
void print()
{
}template <typename T,typename... Types>
void print(const T& firstArg,const Types&... args)
{
cout << firstArg << " sizeof(args) " << sizeof...(args) << endl;
print(args...);
}
模板引數Types:在模板引數 Types 左邊出現省略號 ... ,就是表示 Types 是一個模板引數包(template type parameter pack)
函式引數args:函式引數args的型別定義一個模板引數包,args是一個可變引數
函式實參args:args是一個可變引數,省略號...出現在其後
sizeof...(args):計算不定模板引數的個數
使用
1. 利用 variadic template 實現printf:
void printf(const char *s)
{
while (*s) {
if (*s == '%') {
if (*(s + 1) == '%') {
++s;
}
else {
throw std::runtime_error("invalid format string: missing arguments");
}
}
std::cout << *s++;
}
}
template<typename T, typename... Args>
void printf(const char *s, T value, Args... args)
{
while (*s) {
if (*s == '%') {
if (*(s + 1) == '%') {
++s;
}
else {
std::cout << value;
// call even when *s == 0 to detect extra arguments
printf(s + 1, args...);
return;
}
}
std::cout << *s++;
}
throw std::logic_error("extra arguments provided to printf");
}
2. 利用遞迴繼承和variadic template 實現 tuple:
template<typename... Elements> class tuple;
template<typename Head, typename... Tail>
class tuple<Head, Tail...> : private tuple<Tail...> {
Head head;
public:
/* implementation */
};
template<>
class tuple<> {
/* zero-tuple implementation */
};
VS2015的測試資訊:
tuple<int, float, string> t(1,2.1,"test");
cout << t._Myfirst._Val << endl;
cout << t._Get_rest()._Myfirst._Val << endl;
cout << t._Get_rest()._Get_rest()._Myfirst._Val << endl;
輸出:
參考文章:
相關文章
- Variadic Templates
- C++11新特性(一):語言特性C++
- C++11新特性(三):語言特性C++
- C++11新特性(二):語言特性C++
- JDK 8 新特性之函數語言程式設計 → Stream APIJDK函數程式設計API
- Rust入門系列之語言特性 - 1Rust
- Java從8到21的語言新特性Java
- Java8 新特性 —— 函數語言程式設計Java函數程式設計
- Python 語言特性:編譯+解釋、動態型別語言、動態語言Python編譯型別
- Java 10 新特性之 AppCDSJavaAPP
- Go 語言的 4 個特性改動Go
- Chrome 71 新特性[雙語+視訊]Chrome
- C語言的角落——這些C語言不常用的特性你知道嗎?C語言
- Java 8 新特性之方法引用Java
- IOS11新特性之maskedCornersiOS
- iOS 8 之後UINavigationController新特性iOSUINavigationController
- ES6 新特性之SymbolSymbol
- JDK8新特性之stream()JDK
- MySQL 8 新特性之Clone PluginMySqlPlugin
- HTML5 新特性之 WebsocketHTMLWeb
- Java8新特性之:OptionalJava
- MySQL 8 新特性之Invisible IndexesMySqlIndex
- C++20語言核心特性的變化C++
- ES6語言特性的總結(3)
- templates
- MySQL8.0新特性-CTE語法支援MySql
- Flutter學習之Dart語法特性FlutterDart
- Go 語言版 Service Mesh Sidecar 剖析系列之 SOFAMosn 的誕生和特性總覽GoIDE
- 如何為Mac新增新語言?Mac
- DPC++中的現代C++語言特性C++
- 值得推薦的C#不同版本語言特性C#
- prometheus之查詢語言Prometheus
- JDK8新特性之Stream流JDK
- JDK 1.8 新特性之Lambda表示式JDK
- ?Java8新特性之Optional類Java
- JDK 9新特性之Flow API 初探JDKAPI
- 開心檔之Java 9 新特性Java
- java8 新特性之方法引用Java