Search code examples
c++rapidxml

Compiler won't let me return a rapidxml::xml_document, and reports errors in the header file


Compiling my three-file program (main.cpp, source.cpp, header.hpp) generates these errors:

source.cpp: In member function ‘rapidxml::xml_document<> MyClass::generate_xml_document()’:
source.cpp:559:9: error: use of deleted function ‘rapidxml::xml_document<>::xml_document(const rapidxml::xml_document<>&)’
In file included from header.hpp:12:0,
                 from source.cpp:11:
rapidxml.hpp:1358:11: error: ‘rapidxml::xml_document<>::xml_document(const rapidxml::xml_document<>&)’ is implicitly deleted because the default definition would be ill-formed:
rapidxml.hpp:1322:9: error: ‘rapidxml::xml_node<Ch>::xml_node(const rapidxml::xml_node<Ch>&) [with Ch = char, rapidxml::xml_node<Ch> = rapidxml::xml_node<char>]’ is private

The named lines are:

  • source.cpp:559 states simply return doc;. It is the end of a function that generates a rapidxml::xml_document<>.
  • header.hpp:12 and source.cpp:11 state #include "rapidxml.hpp".
  • The area around rapidxml.hpp:1322 states:

    private:
        // Restrictions
    
        // No copying
        xml_node(const xml_node &);
        void operator =(const xml_node &);
    
  • rapidxml.hpp:1358 is the beginning of the class xml_document: class xml_document: public xml_node<Ch>, public memory_pool<Ch>

Is this a mistake in rapidxml? (I'm pretty sure it isn't, because Marcin Kalicinski is definitely a better programmer than I.)


Solution

  • Basically, RapidXML xml_document type is non-copyable. As the snippet you post shows (and the comment "No copying" implies), the copy constructor and assignment operator are private to force compiler errors.

    You should either dynamically create one in your function, and return a pointer - or, make the function take a reference to an existing xml_document as an input.

    So instead of this

    xml_document myFunc() 
    { 
      xml_document doc;
      ...
      return doc; 
    }
    
    xml_document d = myfunc();
    

    ..you'll need this

    void myFunc(xml_document &doc) 
    {
      ... 
    }
    
    xml_document d;
    myfunc(d);
    

    Or, using dynamic allocation:

    xml_document *myFunc() 
    { 
      xml_document *doc = new xml_document();
      return doc; 
    }
    
    xml_document d = myfunc();
    ...
    delete d;
    

    The latter obviously needs smart pointers, but this shows the idea.