[英]Non-pointer function type can be a non-type parameter?
我一直在試驗C ++中的函數類型。 請注意,我的意思不是指向函數的指針類型,例如:
typedef void (*voidFuncPtr)();
但更加奇特:
typedef void (voidFunc)();
我沒想到會編譯以下代碼,但是令人驚訝的是:
template<voidFunc func>
class funcClass
{
public:
void call() { func(); };
};
void func()
{ }
void Test()
{
funcClass<func> foobar;
foobar.call();
}
但是,如果我嘗試將以下內容添加到funcClass:
voidFuncPtr get() { return &func; }
我收到錯誤Address expression must be an lvalue or a function designator
我的第一個問題是:編譯器用來假裝func類型實際上是可以傳遞給實例的東西? 只是把它當作參考? 第二個問題是:如果它甚至可以被調用,為什么不能使用它的地址? 另外,這些非指針功能類型稱為什么? 我只是因為boost :: function而發現了它們,卻從未找到關於它們的任何文檔。
該標准的第14.1.4節規定:
非類型模板參數應具有以下(可選,具有cv限定)類型之一:
—整數或枚舉類型,
—指向對象的指針或指向函數的指針 ,[ 這就是你的 ]
—對對象的左值引用或對函數的左值引用,
—指向成員的指針,
— std :: nullptr_t。
§14.1.6說
非類型非參考模板參數是prvalue。 不得將其賦值或以任何其他方式更改其值。 非類型非引用模板參數不能采用其地址 。 當非類型非引用模板參數用作引用的初始化程序時,始終使用臨時變量。
這樣就可以解釋您所看到的兩種行為。
請注意, func
與&func
(§14.3.2.1)相同:
[非類型模板參數可以是]一個常數表達式(5.19),該常數指定具有靜態存儲期限和外部或內部鏈接的對象的地址,或者具有外部或內部鏈接的函數,包括函數模板和函數模板ID,但不包括非靜態類成員,表示為&id-expression(忽略括號),但如果名稱是指函數或數組 ,則可以省略&;如果相應的template-parameter是引用,則應省略; 要么...
因此,它只是一個函數指針。
假定代碼編譯時沒有地址操作符和指針(包括函數和成員函數的指針)是有效的模板參數,似乎編譯器認為voidFunc
是函數指針類型,即該類型的衰減版本。 在C ++ 2003和C ++ 2011之間,此規則不變。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.