簡體   English   中英

模板非類型參數,C ++ 11,字符串文字的限制

[英]Template Non-Type argument, C++11, restriction for string literals

模板非類型參數的限制規則說:

非類型非模板模板參數的模板參數應為以下之一:

- 對於整數或枚舉類型的非類型模板參數,模板參數類型的轉換常量表達式(5.19); 要么

- 非類型模板參數的名稱; 要么

- 一個常量表達式(5.19),用於指定具有靜態存儲持續時間和外部或內部鏈接的對象的地址,或具有外部或內部鏈接的函數,包括函數模板和函數模板ID,但不包括非靜態類成員,表達(忽略括號)as&id-expression,除非如果名稱引用函數或數組,則可以省略&,如果相應的template-parameter是引用,則省略; 要么

- 一個常量表達式,其值為空指針值(4.10); 要么

- 一個常量表達式,其值為null成員指針值(4.11); 要么

- 指向成員的指針,如5.3.1中所述。

2 [ 注意:字符串文字(2.14.5)不滿足任何這些類別的要求,因此不是可接受的模板參數。

[ Example:
template<class T, const char* p> class X {
/ ... /
};
X<int, "Studebaker"> x1; // error: string literal as template-argument
const char p[] = "Vivisectionist";
X<int,p> x2; // OK
—end example ] —end note ]

那么為什么字符串文字不能用作非類型參數的參數?

const char arr[5] = "1234";

arr具有相同的類型const char [5]

"1234"; 

arr具有外部鏈接,這就是為什么允許在c ++ 11標准之前使用arr作為非類型模板參數。

但是現在指向具有內部鏈接(靜態存儲)的對象的指針也允許用作非類型模板參數,而字符串文字具有內部鏈接。

從你的問題來看,最接近字符串文字的是:

一個常量表達式(5.19),用於指定具有靜態存儲持續時間和外部或內部鏈接的對象的地址

字符串文字既沒有外部鏈接也沒有內部鏈接,因此不允許使用它們。

如果你有多個翻譯單元,每個翻譯單元都包含const char arr[5];的定義const char arr[5]; 通過內部鏈接,那些都是不同的對象,具有不同的地址,但在單個翻譯單元中, arr == arr ,始終。 實現找到了如何使模板參數工作。

如果您有多個翻譯單元,每個單元包含"1234"則不保證這些單元具有不同的地址。 然而,即使在單個翻譯單元中,也不能保證它們具有相同的地址。

如果"1234" != "1234" ,則引用模板S<"1234">沒有意義:每次都要引用不同的模板實例化。

如果"1234" == "1234" ,則實現變得復雜以確保S<"1234">在每個翻譯單元中是相同的類型。

真的很有趣,以下代碼是有效的C ++ 11,但字符串文字將無法正常工作。 對於C ++ 14,您甚至可以刪除static_cast。

#include <iostream>

static constexpr const char s1[] = "Hello World!";
static const char s2[] = __DATE__ " " __TIME__;

template< const char* STR > struct X {X() {std::cout << STR << std::endl;}};
X< s1 > x1;
X< static_cast<const char*>(s2) > x2;

int main() {}

即使今天的C ++編譯器不接受字符串文字,在某些情況下允許這樣做會非常方便。

接受臨時類實例化的地址作為NT模板參數將進入類似的方向:

#include <iostream>

struct S {int s;};
static constexpr const S s1{123};
static const S s2{999};

template< const S* _S > struct X {X() {std::cout << _S->s << std::endl;}};
X< &s1 > x1;
X< &s2 > x2;
//NOT OK: X< (&S{1}) > x3;

int main() {}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM