最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++詳解非類型模板參數(shù)Nontype與Template及Parameters的使用

 更新時(shí)間:2022年06月24日 09:03:58   作者:loongknown  
除了類型可以作為模板參數(shù),普通值也可以作為模板函數(shù),即非類型模板參數(shù)(Nontype Template Parameters)。下面讓我們一起了解一下

非類型類模板參數(shù)

前一章使用的例子 Stack 使用的是標(biāo)準(zhǔn)庫(kù)中的容器管理元素,也可以使用固定大小的 std::array,它的優(yōu)勢(shì)是內(nèi)存管理開銷更小,數(shù)組的大小可以交給用戶指定。

#include <array>
#include <cassert>
template<typename T, std::size_t Maxsize>
class Stack {
  private:
    std::array<T,Maxsize> elems; // elements
    std::size_t numElems; // current number of elements
  public:
    Stack(); // constructor
    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 numElems == 0;
    }
    std::size_t size() const { // return current number of elements
      return numElems;
    }
};
template<typename T, std::size_t Maxsize>
Stack<T,Maxsize>::Stack ()
 : numElems(0) // start with no elements
{
  // nothing else to do
}
template<typename T, std::size_t Maxsize>
void Stack<T,Maxsize>::push (T const& elem)
{
  assert(numElems < Maxsize);
  elems[numElems] = elem; // append element
  ++numElems; // increment number of elements
}
template<typename T, std::size_t Maxsize>
void Stack<T,Maxsize>::pop ()
{
  assert(!elems.empty());
  --numElems; // decrement number of elements
}
template<typename T, std::size_t Maxsize>
T const& Stack<T,Maxsize>::top () const
{
  assert(!elems.empty());
  return elems[numElems-1]; // return last element
}
int main()
{
  Stack<int,20> int20Stack; // stack of up to 20 ints
  Stack<int,40> int40Stack; // stack of up to 40 ints
  Stack<std::string,40> stringStack; // stack of up to 40 strings
  // manipulate stack of up to 20 ints
  int20Stack.push(7);
  std::cout << int20Stack.top() << '\n';
  int20Stack.pop();
  // manipulate stack of up to 40 strings
  stringStack.push("hello");
  std::cout << stringStack.top() << '\n';
  stringStack.pop();
}

使用該模板需要同時(shí)指定類型和個(gè)數(shù)。 Maxsize 用于指定 std::array 的大小。非類型模板參數(shù)也可以有默認(rèn)值。

template<typename T = int, std::size_t Maxsize = 100>
class Stack {
  ...
};

非類型函數(shù)模板參數(shù)

也可以為函數(shù)定義非類型模板參數(shù)。

template<int Val, typename T>
T addValue (T x)
{
  return x + Val;
}
std::transform (source.begin(), source.end(), // start and end of source
                dest.begin(), // start of destination
                addValue<5,int>); // operation

也可以指定一個(gè)模板參數(shù),由該參數(shù)之前的參數(shù)推斷出其類型。

template<auto Val, typename T = decltype(Val)>
T foo();

或者保證傳值的類型和指定的類型相同。

template<typename T, T Val = T{}>
T bar();

非類型模板參數(shù)的限制

需要注意的是,非類型模板參數(shù)有一定的限制。一般地,非類型模板參數(shù)可以是整形(包括枚舉)、指向?qū)ο?函數(shù)/成員的指針、對(duì)象/函數(shù)的左值引用或空指針類型 std::nullptr_t。

浮點(diǎn)數(shù)和類類型對(duì)象不可以作為非類型模板參數(shù)。

template<double VAT>        // ERROR: floating-point values are not
double process (double v)   // allowed as template parameters
{
  return v * VAT;
}
template<std::string name>  // ERROR: class-type objects are not
class MyClass {             // allowed as template parameters
  ...
};

當(dāng)使用指針或引用作為非類型模板參數(shù)時(shí),不能用字符串字面值、臨時(shí)對(duì)象、數(shù)據(jù)成員或其他子對(duì)象作模板實(shí)參。

template<char const* name>
class MyClass {
  ...
};
MyClass<"hello"> x; // ERROR: string literal "hello" not allowed

C++版本逐漸放寬了限制。C+11 之前,對(duì)象必須有外部鏈接;C++17 之前對(duì)象必須有外部或內(nèi)部鏈接;C++17 放開了此限制。

extern char const s03[] = "hi"; // external linkage
char const s11[] = "hi"; // internal linkage
int main()
{
  MyClass<s03> m03; // OK (all versions)
  MyClass<s11> m11; // OK since C++11
  static char const s17[] = "hi"; // no linkage
  MyClass<s17> m17; // OK since C++17
}

非類型模板參數(shù)的實(shí)參可能是任何編譯期表達(dá)式。

template<int I, bool B>
class C;
...
C<sizeof(int) + 4, sizeof(int)==4> c;

當(dāng)表達(dá)式中使用了大于號(hào),需要將整個(gè)表達(dá)式用小括號(hào)括起來(lái)。

C<42, sizeof(int) > 4> c; // ERROR: first > ends the template argument list
C<42, (sizeof(int) > 4)> c; // OK

非類型模板參數(shù) auto

從 C++17 開始, 可以將非類型模板參數(shù)定義為 auto,以接收任何允許作為非類型模板參數(shù)的類型。

#include <array>
#include <cassert>
template<typename T, auto Maxsize>
class Stack {
  public:
    using size_type = decltype(Maxsize);
  private:
    std::array<T,Maxsize> elems; // elements
    size_type numElems; // current number of elements
  public:
	Stack();  // constructor
	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 numElems == 0;
	}
	size_type size() const { // return current number of elements
	  return numElems;
	}
};
// constructor
template<typename T, auto Maxsize>
Stack<T,Maxsize>::Stack ()
 : numElems(0) // start with no elements
{
  // nothing else to do
}
template<typename T, auto Maxsize>
void Stack<T,Maxsize>::push (T const& elem)
{
  assert(numElems < Maxsize);
  elems[numElems] = elem; // append element
  ++numElems; // increment number of elements
}
template<typename T, auto Maxsize>
void Stack<T,Maxsize>::pop ()
{
  assert(!elems.empty());
  --numElems; // decrement number of elements
}
template<typename T, auto Maxsize>
T const& Stack<T,Maxsize>::top () const
{
  assert(!elems.empty());
  return elems[numElems-1]; // return last element
}

從 C++14 開始,已經(jīng)支持使用 auto 作為函數(shù)返回值。因此成員函數(shù) size() 可以簡(jiǎn)寫為:

auto size() const { // return current number of elements
  return numElems;
}

上述模板的使用:

int main()
{
  Stack<int,20u> int20Stack; // stack of up to 20 ints
  Stack<std::string, 40> stringStack; // stack of up to 40 strings
  // manipulate stack of up to 20 ints
  int20Stack.push(7);
  std::cout << int20Stack.top() << '\n';
  auto size1 = int20Stack.size();
  stringStack.push("hello");
  std::cout << stringStack.top() << '\n';
  auto size2 = stringStack.size();
  if (!std::is_same_v<decltype(size1), decltype(size2)>) {
    std::cout << "size types differ" << '\n';
  }
}

前面說(shuō)過(guò),非類型模板參數(shù) auto 接收任何允許作為非類型模板參數(shù)的類型。

#include <iostream>
template<auto T> // take value of any possible nontype parameter (since C++17)
class Message {
  public:
   void print() {
     std::cout << T << '\n';
   }
};
int main()
{
  Message<42> msg1;
  msg1.print(); // initialize with int 42 and print that value:42
  static char const s[] = "hello";
  Message<s> msg2; // initialize with char const[6] "hello"
  msg2.print(); // and print that value:hello
}

非類型模板 auto 的參數(shù)仍不能是浮點(diǎn)數(shù)。

Stack<int,3.14> sd; // ERROR: Floating-point nontype argument

使用 decltype(auto) 指定非類型模板參數(shù)的類型也是可以的。

template<decltype(auto) N>
class C {
  ...
};
int i;
C<(i)> x; // N is int&

參考 http://www.tmplbook.com

到此這篇關(guān)于C++詳解非類型模板參數(shù)Nontype與Template及Parameters的使用的文章就介紹到這了,更多相關(guān)C++非類型模板參數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • linux下實(shí)現(xiàn)的2048游戲示例分享

    linux下實(shí)現(xiàn)的2048游戲示例分享

    這篇文章主要介紹了linux下實(shí)現(xiàn)的2048游戲示例,需要的朋友可以參考下
    2014-04-04
  • linux中查詢dns示例

    linux中查詢dns示例

    這篇文章主要介紹了linux中查詢dns示例,需要的朋友可以參考下
    2014-04-04
  • VScode如何調(diào)用KEIL-MDK

    VScode如何調(diào)用KEIL-MDK

    這篇文章主要介紹了VScode如何調(diào)用KEIL-MDK問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 基于C語(yǔ)言實(shí)現(xiàn)靜態(tài)通訊錄的示例代碼

    基于C語(yǔ)言實(shí)現(xiàn)靜態(tài)通訊錄的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用C語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的靜態(tài)通訊錄,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語(yǔ)言有一定幫助,需要的可以參考一下
    2022-07-07
  • c++多線程為何要使用條件變量詳解

    c++多線程為何要使用條件變量詳解

    多線程是多任務(wù)處理的一種特殊形式,下面這篇文章主要給大家介紹了關(guān)于c++多線程為何要使用條件變量的相關(guān)資料,需要的朋友可以參考下
    2021-06-06
  • 使用Qt生成Word和PDF文檔的詳細(xì)教程

    使用Qt生成Word和PDF文檔的詳細(xì)教程

    Qt 是一個(gè)跨平臺(tái)的應(yīng)用程序開發(fā)框架,除了用于創(chuàng)建圖形界面應(yīng)用程序外,還可以用來(lái)生成 Word 和 PDF 文檔,本文將介紹如何使用 Qt 來(lái)生成Word和PDF文檔,以及相關(guān)的代碼示例,需要的朋友可以參考下
    2023-10-10
  • C語(yǔ)言快速排序函數(shù)用法(qsort)

    C語(yǔ)言快速排序函數(shù)用法(qsort)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言的快排函數(shù)用法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • C語(yǔ)言如何計(jì)算字符串長(zhǎng)度

    C語(yǔ)言如何計(jì)算字符串長(zhǎng)度

    這篇文章主要介紹了C語(yǔ)言如何計(jì)算字符串長(zhǎng)度問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 聊聊C++中右值引用和移動(dòng)構(gòu)造函數(shù)的使用

    聊聊C++中右值引用和移動(dòng)構(gòu)造函數(shù)的使用

    這篇文章主要是來(lái)和大家一起聊聊C++中右值引用和移動(dòng)構(gòu)造函數(shù)的使用,文中通過(guò)示例進(jìn)行了詳細(xì)講解,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-07-07
  • C++連接mysql數(shù)據(jù)庫(kù)的兩種方法小結(jié)

    C++連接mysql數(shù)據(jù)庫(kù)的兩種方法小結(jié)

    這篇文章主要介紹了C++連接mysql數(shù)據(jù)庫(kù)的兩種方法小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04

最新評(píng)論

老河口市| 高平市| 闸北区| 临猗县| 常山县| 毕节市| 株洲市| 宁晋县| 华阴市| 依安县| 郸城县| 壤塘县| 武功县| 定边县| 甘孜| 河北区| 惠东县| 黑水县| 金堂县| 长阳| 商水县| 十堰市| 永兴县| 东乡县| 湛江市| 墨玉县| 久治县| 山阳县| 湖北省| 社会| 越西县| 莆田市| 香河县| 甘泉县| 宝山区| 铜鼓县| 专栏| 霍山县| 镇雄县| 海宁市| 富顺县|