[英]C++ dereference happens after implicit conversion
今天,我看到嘗試在函數調用中取消引用參數時,隱式轉換發生在實際的取消引用操作之前(我相信只有在原始類型不支持取消引用的情況下)。
可以在這里看到此觀察結果:
struct A{};
struct C
{
C(const A&)
{
}
};
C operator*(const C&);
double f(C);
template <typename T>
struct t
{
static const bool value = sizeof(f(**static_cast<T*>(NULL))) == sizeof(double);
};
int main(int argc, const char * argv[]) {
t<A>::value;
}
C ++標准是否明確提到了此行為? 謝謝。
讓我們看一下這個表達式:
f(**static_cast<A*>(NULL))
從最內層到最外層, static_cast<A*>(NULL)
std::declval<A*>()
static_cast<A*>(NULL)
是一個A*
(盡管更喜歡nullptr
而std::declval<A*>()
NULL
,並且還更喜歡使用std::declval<A*>()
獲得“類型為A*
東西”,而不是老式的空指針方法轉換)。
接下來, *(a prvalue of type A*)
為您提供類型為A
的左值。 這就是指針取消引用的含義,並且它不可重載。 事情容易推理的時候很好。
接下來, *(an lvalue of type A)
。 為了弄清楚這意味着什么,我們將調用轉換為函數符號,我們的候選集是:
A::operator*()
operator*(a)
,在表達式的上下文中對operator*()
進行無限定的查找。 第一個項目符號什么也找不到,沒有A::operator*()
。 第二個項目符號,即對operator*()
無限定查找將找到函數C operator*(const C&);
因為它在范圍內。 這是一個可行的候選人,因為A
可以通過C(A const&)
轉換為C
第三個子彈沒有可行的候選人。
由於我們只有一個可行的候選者,因此它是最佳可行的候選者-因此*(lvalue of type A)
提供了C
類型的prvalue。
具體回答您的問題:
隱式轉換發生在實際的取消引用操作之前
是的,必須進行轉換才能解決取消引用操作。 盡管實際上不是“取消引用”,但它只是一元運算operator*()
。
最后, f(prvalue of type C)
調用我們擁有的f
,它使我們獲得double
。
請注意,在現代C ++中,我建議將支票寫得更接近:
template <typename T>
struct t
: std::is_same<
decltype(f(*std::declval<T>())), // <== the type we get when we call f
// on a dereferenced T
double>
{ };
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.