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