Jump to content
  • Advertisement
Sign in to follow this  
Decrius

[C++] " request for member function ... non-class type"

This topic is 3441 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I get the following error:
E:\C\main.cpp:173: error: request for member `retain' in `foo',
which is of non-class type `Pointer<Foo> ()(Foo
(*)())'
E:\C\main.cpp:174: error: request for member `release' in `foo',
which is of non-class type `Pointer<Foo> ()(Foo
(*)())'
Which is rather strange if you consider the following code:
    template <class T>
    class Pointer
    {
    public:
        Pointer(T instance = T())
        {
            _pointer = new T(instance);
        }

        Pointer(T *instance)
        {
            _pointer = new T(*instance);
        }

        ~Pointer()
        {
            release();
        }

        // shouldn't use this one really
        T *pointer()
        {
            return _pointer;
        }

        // get the pointer, increase the count
        T *retain()
        {
            if (_pointer)
            {
                _pointer->references.gain();
            }
            return _pointer;
        }

        // decrease the count
        void release()
        {
            if (_pointer && !_pointer->references.lose())
            {
                delete _pointer;
                _pointer = NULL;
            }
        }

    private:
        T *_pointer;
    };

    ////////////////////////////////////////////////////////////////

    class Foo
    {
        // irrelevant
    };

int main()
{
    Pointer<Foo> foo(Foo()); // creates a new instance of Foo

    foo.retain(); // increases counter
    foo.release(); // decreases counter

    // pointers life time ends -> counter decreased -> Foo is deleted
}
Sure, it works if I do 'Pointer<Foo> foo;' but what is above should do exactly the same, that is, constructing a default Foo object. This is a test code, and the Foo's constructor would in almost all case accept parameters. Preferably I'd like this on one line. The following 2 example _DO_ work:
int main()
{
    Pointer<Foo> foo1;

    Foo tmp(/* parameters*/);
    Pointer<Foo> foo2(tmp);
}
Why does it give this weird error? It looks like it takes it as a function pointer...? PS: I can't (de)allocate (new / delete) in the main() function since the library could be compiled as a DLL, meaning I have to allocate on the lib and deallocate on the lib (or on the executable of course, but I choose the former). Thanks!

Share this post


Link to post
Share on other sites
Advertisement
Im guessing you're a victim of "C++'s most vexing parse". Google for it and you will find better explanations than I can give you. Here is one link:
http://staff.it.uts.edu.au/~ypisan/programming/stl50.html

You can also look it up in one of Scott Meyer's books if you own a copy.

Share this post


Link to post
Share on other sites
Changing that line to this should work:
Pointer<Foo> foo((Foo()));

Basically the compiler decides you were declaring a function instead of a variable. That line can be interpreted as either one. When in doubt the compiler favours functions in this case.

Share this post


Link to post
Share on other sites
This only works if the constructor is implicit though. There should be no problem for it to be explicit though, since it doesn't seem to do any dangerous thing such as ownership transfer.

However, your type obviously lacks a copy constructor and an assignment operator.

Share this post


Link to post
Share on other sites
Quote:
Original post by phresnel
Alternatively, you can write
*** Source Snippet Removed ***
which will call the (same) copy ctor.


Ah yes, you surprised me with that but it's indeed true. On initialisation operator= can be interpreted as if a constructor was called.

Quote:
Original post by loufoque
This only works if the constructor is implicit though. There should be no problem for it to be explicit though, since it doesn't seem to do any dangerous thing such as ownership transfer.

However, your type obviously lacks a copy constructor and an assignment operator.


Good that you mention it, almost forgotten ;).

[Edited by - Decrius on April 20, 2009 11:37:49 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
Ah yes, you surprised me with that but it's indeed true. On initialisation operator= can be interpreted as if a constructor was called.


It's not operator=, and it's not "can be interpreted". The initialization syntax with '=' calls the copy constructor, not operator=. Why? Because it's an initialization. You can't assign to something that hasn't been initialized yet, because an uninitialized thing (except for primtives) effectively doesn't exist yet.

You could also avoid the "vexing parse" by using a named temporary for the Foo object: Foo f; Pointer<Foo> foo(f);

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!