vendredi 23 juin 2023

Why must I use this-> to call shared_from_this()? [duplicate]

I have some code in a multi platform project, that compiles fine with visual studio, but fails to compile with g++ and clang++, when I call shared_from_this(), instead of this->shared_from_this().

I was able to strip it down to this minimal code example:

#include <memory>

struct class1: public std::enable_shared_from_this<class1>
{
    template<typename T>
    struct class2: public std::enable_shared_from_this<class2<T>>
    {
        void func()
        {
            this->shared_from_this(); // this works
            shared_from_this(); // this gives an error ???
        }
    };
};

void foo()
{
    class1::class2<int>().func();
}

g++ gives this error:

$ g++ -c bug.cpp
bug.cpp: In instantiation of ‘void class1::class2<T>::func() [with T = int]’:
bug.cpp:18:28:   required from here
bug.cpp:11:41: error: cannot call member function ‘std::shared_ptr<_Tp> std::enable_shared_from_this<_Tp>::shared_from_this() [with _Tp = class1]’ without object
   11 |                         shared_from_this(); // this gives an error ???
      |                         ~~~~~~~~~~~~~~~~^~

clang++ gives this error:

$ clang++ -c bug2.cpp
bug.cpp:11:4: error: call to non-static member function without an object argument
                        shared_from_this(); // this gives an error ???
                        ^~~~~~~~~~~~~~~~
bug.cpp:18:24: note: in instantiation of member function 'class1::class2<int>::func' requested here
        class1::class2<int>().func();
                              ^

Both compiler agree in that I want to call a member function without an instance and yes, I have not explicitly specified this as the instance to use. But shouldn't I be able to call member functions on this instance without explicitly specifying this->?

I tried to further strip down the code by removing the outer class and got this code, that also does not compile, but gives a different error message:

#include <memory>

template<typename T>
struct class1: public std::enable_shared_from_this<class1<T>>
{
    void func()
    {
        this->shared_from_this(); // this works
        shared_from_this(); // this gives an error ???
    }
};

void foo()
{
    class1<int>().func();
}

g++ now gives this error:

$ g++ -c bug1.cpp
bug1.cpp: In member function ‘void class1<T>::func()’:
bug1.cpp:9:17: error: there are no arguments to ‘shared_from_this’ that depend on a template parameter, so a declaration of ‘shared_from_this’ must be available [-fpermissive]
    9 |                 shared_from_this(); // this gives an error ???
      |                 ^~~~~~~~~~~~~~~~
bug1.cpp:9:17: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)

clang++ now gives this error:

+ clang++ -c bug1.cpp
bug1.cpp:9:3: error: use of undeclared identifier 'shared_from_this'
                shared_from_this(); // this gives an error ???

Is my code really buggy (and if yes, why?), or is this a common bug in g++ and clang++?

Aucun commentaire:

Enregistrer un commentaire