Search code examples
c++classincompatibletypeerror

Declaration is not compatible with “Message::save(<error-type>& fol)”


In Message.h, I define two classes: Message, Folder. And when I try to define a member function save() for Message, it says :Declaration is not compatible with “Message::save(& fol)”. This error happens in the definition part for save() and remove().

However, I check that Folder& in the declaration should be the same as Folder& in the definition. And the Folder class is defined below as well. Thus I wonder why it says Folder is an error-type.

class Message {
    friend class Folder;
public:
...
    //save and remove message from given folder
    void save(Folder& fol);
    void remove(Folder& fol);
...
private:
    std::string contents;
    std::set<Folder*> folders;
}

void Message::save(Folder& fol) {
    folders.insert(&fol);
    fol.addMsg(*this);
}

void Message::remove(Folder& fol) {
    folders.erase(&fol);
    fol.remMsg(*this);
}

...

class Folder{
       friend class Message;
...
}
...


Solution

  • Different compilers might tell you this error in different ways, but there are a couple things you need to change:

    1. You need to forward-declare Folder by adding class Folder; before the declaration of Message. The friend class declaration doesn't count.

    2. You need to define Folder before you define Message::save and Message::remove. The reason is (put simply) that the compiler can only work with what information is provided above when compiling a part of a program, and so far you've only told it that Folder is a class that exists, which is enough to declare a pointer or reference to it, but not enough to use a value of that type (for example, it would have no idea what the signature of fol.addMsg is, or if it even exists). If you reorder accordingly so that all class definitions come before all function definitions (as would be the case in any normal usage of header and source files), it should compile.

    For reference, this compiles:

    #include <string>
    #include <set>
    
    class Folder;
    
    class Message {
        friend class Folder;
    public:
        //save and remove message from given folder
        void save(Folder& fol);
        void remove(Folder& fol);
    private:
        std::string contents;
        std::set<Folder*> folders;
    };
    
    class Folder{
        friend class Message;
        void addMsg(Message &);
        void remMsg(Message &);
    };
    
    void Message::save(Folder& fol) {
        folders.insert(&fol);
        fol.addMsg(*this);
    }
    
    void Message::remove(Folder& fol) {
        folders.erase(&fol);
        fol.remMsg(*this);
    }
    
    void Folder::addMsg(Message &) {}
    
    void Folder::remMsg(Message &) {}
    

    Hope this helps.