簡體   English   中英

非指針函數類型可以是非類型參數嗎?

[英]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.

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