Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-dev] Parser error (friend to namespace members)

Hey guys,

As a part of my quest to turn Java "programmers" into programmers I dazzle them with RAII and scopes! Unfortunately Eclipse CDT reports an error that isn't actually an error. I refreshed/rebuilt my index and all, Eclipse is still not happy, it also makes sense that this is a parse error because it's one of those edge cases.

The error basically is as follows:

When defining a friendly function to that exists in a different namespace the parser fails to resolve it; claiming "No member found". This suggests it it interprets the friend declaration as a function in another class. Obviously it fails to find that class (because the name refers to a namespace), hence the error.

I have no doubt that classes are a subclass (or implement the same interface as) namespaces, after all they are very similar and such a thing should be easy to fix.

The C++(all of them) state symbols (functions, variable,...) must be unique (hence name mangling), so no valid program can/would have a namespace and a class sharing a name.

While I have not seen Eclipse-CDTs code, I would imagine there is a method that tests for the presence of a symbol in a namespace (and by inheritance classes). So the fix should be simple, if (when analysing the friend declaration) the symbol is not found in the collection of classes in the current scope, try the collection of namespaces in the current scope.

This also brings up a point about implementation.
The list of all the namespaces in the current scope should be the union of the actual namespaces in the current scope, the classes in the current scope and any using/typedef declarations that bring a namespace into the current scope (where this namespace refers to an actual namespace, class or using/typedef ...) A method like "isClass" "isActualNamespace" and "isAlias" would help with these.

Anyway! Code to reproduce the error:

#ifndef REFCOUNT_H_
#define REFCOUNT_H_

template<class> class RCP;
namespace SmartPointers {
using ::RCP;
    template<class T> int getReferenceCount(const RCP<T>&);
}

template<class T>
class RCP {
public:
    template<class ... ARG_TYPES> RCP(ARG_TYPES ... args) {
        refCount = new int;
        *refCount = 1;
        data = new T(args...);
    }
    RCP(const RCP& rhs) {
        refCount = rhs.refCount;
        data = rhs.data;
        *refCount += 1;
    }
    RCP& operator=(const RCP& rhs) {
        refCount = rhs.refCount;
        data = rhs.data;
        *refCount += 1;
        return *this;
    }
    ~RCP() {
        *refCount -= 1;
        if(*refCount == 0) {
            delete data;
            delete refCount;
        }
    }
private:
    int* refCount;
    T* data;

friend int SmartPointers::getReferenceCount<T>(const RCP<T>&);
};

namespace SmartPointers {
template<class T> int getReferenceCount(const RCP<T>& ref) {
    return *ref.refCount;
}
}


#endif /* REFCOUNT_H_ */

Alec


Back to the top