[英]Should name lookup be deferred for a dependent class/namespace-name in a class-member-access expression?
[英]Should a name found in a dependent base class hide a namespace name at the point of instantiation?
使用以下代碼,clang 3.0給出了error: lookup of 'N' in member access expression is ambiguous
,而clang 3.4和gcc 4.8都接受了該代碼而沒有錯誤。
struct B
{
struct M
{
void f()
{
}
};
};
namespace N
{
struct M
{
void f()
{
}
};
}
template<typename>
struct A : N::M, B::M
{
typedef B N;
};
struct D : A<int>
{
A<int> m;
void f()
{
m.N::M::f(); // found class-name 'A<int>::N' (unambiguous)
}
};
template<typename T>
struct C : A<T>
{
A<T> m;
void f()
{
m.N::M::f(); // found namespace-name 'N' (ambiguous?)
}
};
template struct C<int>;
在查閱了標准之后,對於C<T>::f()
的表達式,我不清楚哪個行為正確。
因為N
在對象表達式n
的類的范圍(是從屬的)和整個后綴表達式的上下文(即函數C<T>::f()
的范圍)的范圍內查找的,所以它必須將查找延遲到實例化點。
在實例化時,如果查找同時找到名稱空間N
和類型定義A<T>::N
,則查找將是不確定的。 N
的聲明僅在A<T>::N
的聲明未隱藏的情況下才可見。
問題是命名空間是否N
應該認為是由被隱藏typedef的A<T>::N
當查找N
“在整個后綴表達式的上下文中”和“在模板的定義的點”。
引用自C ++工作草案標准N3242 = 11-0012(2011年2月):
3.4.5類成員訪問[basic.lookup.classref]
如果類成員訪問中的id-expression是以下形式的合格ID
class-name-or-namespace-name::...
之后的類名或命名空間名
.
或->
運算符可在整個postfix-expression的上下文中以及在對象表達式的類范圍內進行查找。 如果僅在對象表達式的類范圍內找到該名稱,則該名稱應引用一個類名稱。 如果僅在整個postfix-expression的上下文中找到該名稱,則該名稱應引用一個類名或名稱空間名。 如果在兩個上下文中都找到了名稱,則類名稱或名稱空間名稱應引用相同的實體。14.6.4從屬名稱解析[temp.dep.res]
在解析從屬名稱時,將考慮以下來源的名稱:
— 在模板定義時可見的聲明。
—來自實例化上下文(14.6.4.1)和定義上下文中與函數參數類型關聯的名稱空間的聲明。
這是在C ++ 11中進行的更改。 您引用的文本來自C ++ 03; 在C ++ 11之前,這是模棱兩可的,因為這兩個查找都被使用了,如果它們找到不同的名稱,那就是錯誤的。 在C ++ 11中,文本為:
如果類成員訪問中的id-expression是形式為class-name-or-namespace-name :: ...的合格ID,則在。之后的class-name-or-namespace-name。 或->運算符首先在對象表達式的類中查找,然后使用名稱(如果找到)。 否則,將在整個postfix-expression的上下文中查找它。 [注意:請參見3.4.3,它描述了::之前的名稱查找,該查找只會查找類型或名稱空間名稱。 —尾注]
基本上,這使類范圍內的查找具有特權,如果找到了名稱,則不會進行其他查找。
關於為什么這只影響標准舊版本中的模板的原因:我認為(很難確定此處的任何內容)是因為在非模板的情況下,在整個后綴的上下文中進行查找-expression還會在基類中找到typedef
,因此兩個查找都解析為同一實體。 對於模板,在整個postfix-expression上下文中的查找不考慮依賴的基類,而僅查找命名空間N
但是,在實例化C
之后,在類范圍內的查找將找到typedef
。 由於兩個查找找到不同的實體,因此名稱綁定是不明確的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.