user1417475
user1417475

Reputation: 236

iso c++ forbids declaration of generic with no type

My native language is C#, so when I started using C++, I wanted to create the get/set sugar syntax for library consumers available in C#.

So I wrote...

template<typename T>
class GetProperty
{
    private:
        T (*get)();
    public:
        GetProperty(T (*get)())
        {
            this->get = get;
        }
        operator T()
        {
            return get();
        }
        template<typename S, typename T>
        GetProperty<S> operator=(GetProperty<T> fool)
        {
            throw 0;
        }
 };

Then, to to use this, I wrote the code:

template<typename T>
class Vector
{
    private:
        struct LinkItem
        {
            public:
                T* Item;
                LinkItem* Next;
                                GetProperty<int> Length (&getLength);
                LinkItem(T* Item = NULL, int length = 1, LinkItem* Next = NULL)
                {
                    this->Item = Item;
                    this->length = length;
                    this->Next = Next;
                }
                LinkItem& operator =(LinkItem rhs)
                {
                    this->Item = rhs.Item;
                    this->length = rhs.length;
                    this->Next = rhs.Next;
                    return *this;
                }
            private:
                 int length;
                 int getLength()
                 {
                     return length;
                 }
        };
        LinkItem* current;
    .
    .
    .
};

However, the C/C++ addition on Netbeans (I believe this is the g++ compiler) claims I am instantiating GetProperty with no type.
According to a Google search, this happens if someone forgets a using statement, or to include a header, etc.
But int is a primitive, so this can't be.
What's going on?

Upvotes: 2

Views: 1085

Answers (2)

bames53
bames53

Reputation: 88155

In addition to the fact that VC++ doesn't implement non-static data member initializers, you can't treat the member function getLength as an int (*)(). Its type is int (LinkItem::*)().

struct Foo {
    int foo(void) {return 1;}
};

int main() {
    int (*var)() = &Foo::foo; // Error
    int (Foo::*var)() = &Foo::foo; // Okay
}

You probably shouldn't be trying to import a foreign idiom like this, but if you really want to you can try something like the following. (Though as Nicol Bolas points out, you also probably shouldn't be implementing your own linked list, or naming it 'vector'. If you're learning C++ just learn the C++ way before going and trying to reinvent things.)

#include <functional>

template<typename T>
class GetProperty
{
private:
    std::function<int()> get;
public:
    GetProperty(std::function<int()> get)
        : get(get)
    {}
    operator T()
    {
        return get();
    }
};

template<typename T>
class Vector
{
private:
    struct LinkItem
    {
    public:
        T* Item;
        LinkItem* Next;
        GetProperty<int> Length;
        LinkItem(T* Item = NULL, int length = 1, LinkItem* Next = NULL)
            : Length([this] { return this->getLength(); })
        {
...

Upvotes: 0

Karolis Juodelė
Karolis Juodelė

Reputation: 3770

You are constructing GetProperty object while declaring it in a struct. That is not allowed in C++. You have to move the construction to the constructor.

Upvotes: 1

Related Questions