this->field 与 C++ 中的 this.field

this->field vs. this.field in C++

(2)(3) 如何在以下 C++ class 中编译,鉴于 this 是一个指针,所以应该需要 ->访问字段的符号(如 (1) 行所示)? (Source)

#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

template <typename T>
class sptr_wrapper
{

private:
    boost::shared_ptr<T> sptr;

public:
    template <typename ...ARGS>
    explicit sptr_wrapper(ARGS... a) 
    {
        this->sptr = boost::make_shared<T>(a...);
    }

    explicit sptr_wrapper(boost::shared_ptr<T> sptr) 
    {
        this->sptr = sptr; // (1)
    }

    virtual ~sptr_wrapper() noexcept = default;

    void set_from_sptr(boost::shared_ptr<T> sptr) 
    {
        this.sptr = sptr; // (2)
    }

    boost::shared_ptr<T> get_sptr() const
    {
        return sptr; // (3)
    }
};

(2)无效。正如你所说,this是一个指针,我们需要使用->而不是.

作为class template的成员,sptr_wrapper::set_from_sptr在使用之前不需要实例化。所以你可以添加一些代码来尝试调用它,然后你可能会如你所料得到编译错误。

This applies to the members of the class template: unless the member is used in the program, it is not instantiated, and does not require a definition.


(3)行有效; sptr指成员sptr,与this->sptr.

作用相同

When a non-static class member is used in any of the contexts where the this keyword is allowed (non-static member function bodies, member initializer lists, default member initializers), the implicit this-> is automatically added before the name, resulting in a member access expression (which, if the member is a virtual member function, results in a virtual function call).

你会相信这个编译的原因是因为这里没有真正编译吗?

显示的代码定义了一个模板。

模板在实例化 class 之前不会变成 "real"。只有在那个时候,编译器才会更仔细地查看模板,并试图弄清楚它在做什么。

当然,在定义模板时,编译器会半心半意地尝试解析模板,但仅勉强足以让自己确信模板由一些看似合理的 C++ 代码组成。

如果您在显示的代码中添加一些额外的行,您将得到您想要的编译错误:

class X {};

void foo()
{
    sptr_wrapper<X> x;
    boost::shared_ptr<X> y;

    x.set_from_sptr(y);
}

这会产生您正在查找的编译错误:

t.C:27:14: error: request for member ‘sptr’ in ‘(sptr_wrapper<X>*)this’, which is of pointer type ‘sptr_wrapper<X>*’ (maybe you meant to use ‘->’ ?)
   27 |         this.sptr = sptr; // (2)

注意仅仅实例化

    sptr_wrapper<X> x;

还不够。在 C++ 编译器眼中它变成 "real" 之前,你必须全力以赴并调用有问题的方法,并且它会阻塞它。

的确,我完全可以想到 "this.foo" 可能是有效 C++ 代码的任何情况,但我确信在构成当前 C++ 标准的 2000 页中的某处,确切的细节正在发生的事情以一种非常迂腐的方式被阐明。

并且您可能会考虑在编译器的错误跟踪器中添加一个注释,这是一个功能请求,让您的编译器在看到类似这样的情况时提前发出友好的警告。