簡體   English   中英

有沒有理由我們無法在未評估的上下文中命名非靜態成員函數?

[英]Is there a reason we cannot name a non-static member function in an unevaluated context?

閱讀[expr.prim.id]時 ,會看到這一點

只能使用表示非靜態數據成員或類的非靜態成員函數的id表達式:

  • 如果該id-expression表示非靜態數據成員,則它出現在未評估的操作數中。

上面的子彈僅適用於數據成員這一事實對我來說並不清楚。 直覺上我希望以下內容形成良好:

#include <type_traits>

using func = int();

class bar {
  func foo; // This is valid, and not the subject of the question
};

static_assert(std::is_same<decltype(bar::foo), func>::value, "No Symmetry!");

但是,即使在檢查靜態斷言之前, decltype()也是不正確的。

是否有一些我不知道的歧義?

是否有一些我不知道的歧義?

事實上,作為該成員函數聲明的一部分添加了大量類型信息。

雖然func肯定可以用來聲明那個成員,但故事並沒有在這里結束。 聲明成員后,它的類型就完成了。 這涉及到添加其他一些東西,比如cv-qualifersref-qualifiers foo的情況下,確定所有默認的隱式,並且它們成為bar::foo類型的一部分。 [dcl.fct] / 8指定:

返回類型,參數類型列表,ref-qualifier,cv-qualifier-seq和異常規范,但不是默認參數,是函數類型的一部分。

在上面的foo聲明中沒有辦法明確指定它們(盡管它們可能被添加到func ),但它們可能會被添加:

class bar {
  int foo() const volatile &&;
};

它們是函數類型的一部分,如果它們出現,則decltype(bar::foo)應該解決它們(如果我正確收集,即使它們沒有)。

當我們嘗試評估decltype(bar::foo)時, const volatile &&在哪里?

  • 應該被忽略嗎? 那可以做到。 但丟失類型信息很少是好事。
  • 我們應該保留它,並且類型decltype計算為指向成員函數的指針嗎?
    這也可行,但現在它與數據成員在未評估的上下文中命名時的行為方式不同。 我們引入了一個差異。
  • 它應該保留,並且類型解決了其他問題嗎? 也許像int(foo const volatile&&)int() const volatile && (另一種形式的函數類型)? 這打破了人們期望的對稱性,並且再次與數據成員產生差異。

沒有簡單或明顯的方法可以讓它始終運作良好。 因此,對於看起來使用有限的功能而言,不要使問題復雜化,最好將其視為不良形式。

是否有一些我不知道的歧義?

我不這么認為。 可能更多的是,確定需要評估非靜態數據成員,而不是非靜態成員函數。

但是,這個:

static_assert(std::is_same<decltype(bar::foo), func>::value, "No Symmetry!");

沒有多大意義。 &bar::foo的類型不是func* ,它是func bar::* 並且沒有一種方法可以拼寫沒有指針,因此必須能夠評估decltype(bar::foo)意味着引入全新的類型語法? 似乎不值得。

請注意, decltype(bar::foo)不能是func因為func是一個函數類型,但bar::foo是一個成員函數。

我沒有看到任何理由。

看這個:

typedef void Func();

Func freeFunction;

struct Foo {
    Func memberFunction;
};

freeFunction的聲明是Func freeFunction; 所以, decltype(freeFunction)void() ,即Func

使用相同的邏輯,As Foo::memberFunction被聲明為Func ,我希望decltype(Foo::memberFunction)也是Func 但事實並非如此,因為這不會編譯。

就像一個int a; decltype(a) int a; decltype(a)解析為int ,即使是int a; 是一個成員, decltype(Foo::memberFunction)應該沒問題。

注意,也可以處理限定符,它們沒有什么特別之處(當然,在這種情況下, Func只能用於聲明非靜態成員函數):

typedef void Func() const volatile &&;

struct Foo {
    Func memberFunction;
};

在這里,我希望decltype(Foo::memberFunction)void() const volatile && ,所以我可以復制它的聲明:

struct Bar {
    decltype(Foo::memberFunction) myMemFn;
};

引用C ++ 14標准(9.2 / 11):

[注意:非靜態成員函數的類型是普通函數類型,非靜態數據成員的類型是普通對象類型。 沒有特殊的成員函數類型或數據成員類型。 - 結束說明]

如果decltype(<member_function>)返回一種普通函數,那么這句話意味着它是明智的。

暫無
暫無

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

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