[英]C++ class member name lookup issues (regarding the wording of standard n3225)
我對標准10.2 / 13感到非常困惑,
[注意:即使名稱查找的結果是明確的,使用在多個子對象中找到的名稱仍然可能是模棱兩可的(4.11、5.2.5、5.3.1、11.2)。
struct B1 {
void f();
static void f(int);
int i;
};
struct B2 {
void f(double);
};
struct I1: B1 { };
struct I2: B1 { };
struct D: I1, I2, B2 {
using B1::f;
using B2::f;
void g() {
f(); // Ambiguous conversion of this
f(0); // Unambiguous (static)
f(0.0); // Unambiguous (only one B2)
int B1::* mpB1 = &D::i; // Unambiguous
int D::* mpD = &D::i; // Ambiguous conversion
}
};
我看不出為什么這是明確的int B1 :: * mpB1 =&D :: i; //明確
Visual C ++,Gcc和CLang都說這是對D :: i的模糊訪問!
該措辭似乎與核心問題#39 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#39有關 ,最終建議在此處: http:// www 。開-std.org / JTC1 / SC22 / WG21 /文檔/文件/ 2004 / n1626.pdf
我現在發現新的基於算法的措詞(10.2 / 3-10.2 / 6)更加令人困惑,因為10.2 / 9、10.2 / 10、10.2 / 11和10.2 / 13中的注釋均未完全符合10.2 / 3。 3-10.2 / 6。 我可以將10.2 / 9-10.2 / 11作為例外,但是我對10.2 / 13感到特別困惑。 我不知道13.2 / 13的意圖。
應該如何根據10.2 / 3-10.2 / 6查找10.2 / 13中的示例? 10.2 / 13的意圖是什么,即10.2 / 13被視為10.2 / 3-10.2 / 6的例外情況是什么?
請給我一些提示。 非常感謝你。
經過一番思考,我認為10.2 / 13的意圖更清晰了。
int B1 :: * mpB1 =&D :: i; //明確
這應該是明確的,當前的編譯器對此是錯誤的。 這是明確的,因為指向類成員初始化的指針尚不涉及訪問對象。
int D :: * mpD =&D :: i; //不明確的轉換
這實際上意味着從int B1 :: * mpB1轉換為int D :: * mpD時,由於基類模棱兩可,因此轉換模棱兩可。
對於B1 :: *情況,解釋是明確的,只是從B1的起始處到i的偏移量。
在5.3.1 / 3中:
struct A { int i; };
struct B : A { };
... &B::i ... // has type int A::*
因此,訣竅是首先使&D :: i的類型為B1 :: *。 然后:
int B1::* mpB1 = &D::i; // Unambiguous
很簡單。 然后產生了興趣:
int D::* mpD = &D::i; // Ambiguous conversion
在這里,RHS的類型為B1 :: *,並且需要進行轉換,因為我們需要確定要引用的是哪個鹼基。
這個:
int B1::* mpB1 = &D::i; // Unambiguous
這是明確的,因為結果已分配給pointer to member
類B pointer to member
的pointer to member
。
因此,選擇哪個i
並不重要,因為偏移是相對於B成員(而不是父D類)而言的。
因此,對於您我來說,這是明確的,但我認為編譯器無法處理。
快速檢查ISO IEC 14882 2003第10節沒有此示例,也沒有類似的示例。 C ++ 0x是草案標准,而VC ++ / GCC / CLang不兼容。
我的猜測:這是新auto
鍵入的一些副產品,在較舊的C ++標准中找不到。
FWIW,我正在復制我給這個問題的Usenet副本的答案:
大家好,
我對標准n3225 10.2 / 13感到非常困惑,
[注意:即使名稱查找的結果是明確的,使用在多個子對象中找到的名稱仍然可能是模棱兩可的(4.11、5.2.5、5.3.1、11.2)。
struct B1 {
void f();
static void f(int);
int i;
};
struct B2 {
void f(double);
};
struct I1: B1 { };
struct I2: B1 { };
struct D: I1, I2, B2 {
using B1::f;
using B2::f;
void g() {
f(); // Ambiguous conversion of this
f(0); // Unambiguous (static)
f(0.0); // Unambiguous (only one B2)
int B1::* mpB1 = &D::i; // Unambiguous
int D::* mpD = &D::i; // Ambiguous conversion
}
};
我看不出為什么這是明確的int B1 :: * mpB1 =&D :: i; //明確
&D::i
類型為int B1::*
,並且明確引用B1
數據成員i
。 如果使用D
對象取消引用或將其分配給int D::*
,則將根據需要獲得歧義。
Visual C ++,Gcc和CLang都說這是對D :: i的模糊訪問!
這些編譯器都沒有實現10.2。
該措辭似乎與核心問題#39 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#39有關 ,最終建議在此處: http:// www .open-std.org / jtc1 / sc22 / wg21 / docs / papers / 2004 / n1626.pdf我現在發現基於算法的新措詞(10.2 / 3-10.2 / 6)更加令人困惑,因為沒有注釋10.2 / 9、10.2 / 10、10.2 / 11和10.2 / 13中的數字完全符合10.2 / 3-10.2 / 6。 我可以將10.2 / 9-10.2 / 11作為例外,但是我對10.2 / 13感到特別困惑。 我不知道13.2 / 13的意圖。
您需要提供示例以說明您不了解的內容。
應該如何根據10.2 / 3-10.2 / 6查找10.2 / 13中的示例? 10.2 / 13的意圖是什么,即在什么情況下10.2 / 13被視為10.2 / 3-10.2 / 6的例外?
基於新算法的查找規則將運行時問題(查找唯一對象)與編譯時間/查找問題(查找名稱所引用的聲明)分離。
以下是采用新措辭的格式:
struct Z { int z; };
struct X : Z { };
struct Y : Z { };
struct A : X, Y { };
struct B : A {
using A::z;
};
聲明using A::x;
在B中引入一個成員名稱,該成員名稱引用聲明Z::z
。 在聲明性上下文中,這完全可以。 僅當您作為成員訪問表達式(5.2.5)訪問B::z
時,才會引發錯誤。
不要因為誤認為成員指針的情況而感到難過。 我過去也這樣做 ,相應的問題報告實際上將其納入了C ++ 0x草案。 當他們發現更改錯誤時,他們很幸運地將其更改回去 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.