C++基本用法實(shí)踐之模板詳解
概述
C++的模板是泛型編程思想的一種實(shí)現(xiàn)。C++是強(qiáng)類型語言,處處強(qiáng)調(diào)類型。同樣的加法運(yùn)算,int和float的加法運(yùn)算需定義兩個函數(shù)(重載),而使用模板則可以只用一個函數(shù)(見下面示例)。
這類似我們面向?qū)ο笏f的多態(tài)(定義加法運(yùn)算,各個類型有不同的實(shí)現(xiàn)),所以是所謂靜多態(tài)的一種實(shí)現(xiàn)方式,不同的是,模板在編譯期展開生成int和float兩個加法函數(shù),如:
template<class T>
T add(T a, T b)
{
return a + b;
}
int v1 = add<int>(1, 2);
// 不顯式聲明模板參數(shù)類型,編譯器會試圖推斷
float v2 = add(1.5f, 2.5f);
/*
實(shí)際上編譯器生成了兩個函數(shù)
int add<int>(int a, int b)
float add<float>(float a, float b)
*/模板不光支持函數(shù)模板,還有類模板等,思想是一樣的(詳情見下面例子)。
模板還有一些特性機(jī)制如:模板特化,SFINAE(substitution failure is not an error 替換而非錯誤),變長參數(shù)模板等,另外模板在元編程中也是十分重要的組成部分,我對元編程沒有太多實(shí)踐,讀者有興趣可以自行搜索。
用法舉例
參考測試項(xiàng)目ModernCppTest/modrenc_template.cpp主要內(nèi)容:
- 函數(shù)模板&Lambda函數(shù)模板
- 類模板
- 別名模板
- 變量模板
- 值(枚舉)作為模板參數(shù)(其實(shí)int類型也可以)
- 模板特化
- 變長參數(shù)模板
- 模板函數(shù)的完美轉(zhuǎn)發(fā)
#include "ModernCppTestHeader.h"
namespace n_template{
template <class T>
void template_func(T t)
{
LOG_VAR(t);
}
template <class T>
class Number
{
public:
T v;
Number(T v) : v(v)
{
LOG_VAR(v);
}
};
template <class T>
constexpr T pi = T(3.1415926f);
template <int INTVAL>
void log_template_int_value()
{
LOG_VAR(INTVAL);
}
enum class EAnim : int {
Other = 0,
Cat = 1,
Dog = 2,
};
template<EAnim Ty>
class Anim
{
public:
void Bark() { LOG("默認(rèn):動物叫"); }
};
template<>
class Anim<EAnim::Dog>
{
public:
void Bark() { LOG("狗:汪汪!"); }
};
template<>
class Anim<EAnim::Cat>
{
public:
void Bark() { LOG("貓:喵喵!"); }
};
// 注意遞歸基
void log_values()
{
LOG("展開結(jié)束");
}
template<class T, class... ARGS>
void log_values(T value, ARGS... args)
{
LOG(value);
log_values(args...);
}
template<class T>
void func_plus(T&& a)
{
auto v = a;
LOG("func_plus v = " << a);
}
template<class T, class... ARGS>
void func_plus(T&& a, T&& b, ARGS... args)
{
func_plus(a + b, std::forward<ARGS>(args)...);
}
template<class T>
void func_mul(T&& a)
{
auto v = a;
LOG("func_mul v = " << a);
}
template<class T, class... ARGS>
void func_mul(T&& a, T&& b, ARGS... args)
{
func_mul(a + b, std::forward<ARGS>(args)...);
}
template <class... ARGS>
void call_func(const std::string& name, ARGS&&... args)
{
if (name == "plus")
func_plus(std::forward<ARGS>(args)...);
else if (name == "mul")
func_mul(std::forward<ARGS>(args)...);
else
LOG("Unknown function name: " << name);
}
}
template<typename T>
using Num = n_template::Number<T>;
void template_test()
{
LOG_FUNC();
LOG_TAG(" 函數(shù)模板 ");
{
n_template::template_func(1);
n_template::template_func(1.25f);
LOG("Lambda 函數(shù)模板");
auto f = []<class T> (T t) { LOG_VAR(t); };
f(1);
f(1.25f);
}
LOG_TAG("類模板");
{
n_template::Number(1);
n_template::Number(1.25f);
}
LOG_TAG("別名模板");
{
Num<int>(1);
Num<float>(1.25f);
}
LOG_TAG("變量模板");
{
auto v1 = n_template::pi<int>;
auto v2 = n_template::pi<float>;
LOG_VAR(v1);
LOG_VAR(v2);
n_template::log_template_int_value<10>();
n_template::log_template_int_value<20>();
}
LOG_TAG("枚舉變量模板&模板特化");
{
n_template::Anim<n_template::EAnim::Dog>().Bark();
n_template::Anim<n_template::EAnim::Cat>().Bark();
LOG("EAnim::Other 沒有特化使用默認(rèn)模板");
n_template::Anim<n_template::EAnim::Other>().Bark();
}
LOG_TAG("變長參數(shù)模板");
{
n_template::log_values("jack", 10, 3.14f);
}
LOG_TAG("變長參數(shù)模板的完美轉(zhuǎn)發(fā)");
{
n_template::call_func("plus", 1, 2, 3, 4);
n_template::call_func("mul", 2, 3);
}
}到此這篇關(guān)于C++基本用法實(shí)踐之模板詳解的文章就介紹到這了,更多相關(guān)C++模板內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言中進(jìn)行大小寫字母轉(zhuǎn)化的示例代碼
C語言標(biāo)準(zhǔn)庫中提供了用于大小寫轉(zhuǎn)換的函數(shù),使得這一操作變得簡單而高效,本文將詳細(xì)介紹如何在C語言中進(jìn)行大小寫字母的轉(zhuǎn)換,包括相關(guān)的函數(shù)和示例代碼,需要的朋友可以參考下2024-03-03
C語言程序設(shè)計(jì)第五版譚浩強(qiáng)課后答案(第二章答案)
這篇文章主要介紹了C語言程序設(shè)計(jì)第五版譚浩強(qiáng)課后答案(第二章答案),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2021-04-04
opencv2實(shí)現(xiàn)10張圖像上下左右拼接融合
這篇文章主要為大家詳細(xì)介紹了opencv2實(shí)現(xiàn)10張圖像上下左右拼接融合,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03
C語言數(shù)據(jù)結(jié)構(gòu)之使用鏈表模擬棧的實(shí)例
這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)之使用鏈表模擬棧的實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-08-08

