繁体   English   中英

隐式转换后发生C ++取消引用

[英]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* (尽管更喜欢nullptrstd::declval<A*>() NULL ,并且还更喜欢使用std::declval<A*>()获得“类型为A*东西”,而不是老式的空指针方法转换)。

接下来, *(a prvalue of type A*)为您提供类型为A的左值。 这就是指针取消引用的含义,并且它不可重载。 事情容易推理的时候很好。

接下来, *(an lvalue of type A) 为了弄清楚这意味着什么,我们调用转换为函数符号,我们的候选集是:

第一个项目符号什么也找不到,没有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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM