0

I have a class with an overloaded insertion operator and it works in my driver:

#include <iostream>
#include <cstdlib>
#include "xml_attribute.h"

int main(){
    using namespace std;

    XML_AttributeT a("name","value");
    cout << a << endl;

    return EXIT_SUCCESS;
}

Outputs: name="value"
works.

I want to leverage this capability in another class that includes this class:
header

#pragma once
#ifndef XML_ELEMENTT_H
#define XML_ELEMENTT_H

#include <string>
#include <vector>
#include <iostream>
#include "xml_attribute/xml_attribute.h"

struct XML_ElementT{

    std::string start_tag;
    std::vector<XML_AttributeT> attributes;
    bool single_tag;

    //Constructors
    explicit XML_ElementT(std::string const& start_tag, std::vector<XML_AttributeT> const& attributes, bool const& single_tag);
    explicit XML_ElementT(void);

    //overloaded extraction operator
    friend std::ostream& operator << (std::ostream &out, XML_ElementT const& element);

};
#endif

cpp

#include "xml_element.h"

//Constructors
XML_ElementT::XML_ElementT(std::string const& tag_, std::vector<XML_AttributeT> const& attributes_, bool const& single_tag_)
: start_tag{tag_}
, attributes{attributes_}
, single_tag{single_tag_}
{}
XML_ElementT::XML_ElementT(void){}

//overloaded extraction operator
std::ostream& operator << (std::ostream &out, XML_ElementT const& element){

    for (std::size_t i = 0; i < element.attributes.size()-1; ++i){
        out << element.attributes[i]; //<- Does not work
    }
    return out;// << element.attributes[element.attributes.size()-1];
}

Error:

undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, XML_AttributeT const&)

how can I get this to work?

chris
  • 60,560
  • 13
  • 143
  • 205
Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
  • Technically that's the insertion operator, not the extraction operator. Even more technically, it's the left shift operator. Also, having both `#pragma once` and the include guard is redundant. The former is just a quicker, non-standard method. – chris Sep 19 '12 at 02:13
  • 2
    @chris http://stackoverflow.com/questions/10779262/does-pragma-once-have-the-potential-to-cause-errors – Trevor Hickey Sep 19 '12 at 02:20
  • 1
    @chris: It's not redundant, adding `#pragma once` can take advantage of faster compiling speeds if the compiler supports it. – Jesse Good Sep 19 '12 at 02:21
  • @Xploit, Ah, I wasn't aware compilers could make optimizations off of that. I'll be putting both in from now on. – chris Sep 19 '12 at 02:22
  • I don't supposed you can include xml_attribute.h/cpp in the source lists above ? – WhozCraig Sep 19 '12 at 02:28
  • @JesseGood: in the same way that include guards can make for faster compiling speeds if the compiler supports it. Many compilers recognize the include guards and if there is no code out of it will not include it the second time. – David Rodríguez - dribeas Sep 19 '12 at 02:28
  • @CraigNelson, This is probably close to the current one: http://stackoverflow.com/questions/12487393/overloaded-operator-outputs-bool-value-why. The missing & in the definition has apparently been fixed. – chris Sep 19 '12 at 02:30
  • @DavidRodríguez-dribeas: Right, but with `#pragma once` there is no need to scan for `#ifndef`, `#endif`, etc. during preprocessing, so it *might* be possible to have faster compilations with pragma once (I'm not sure how much in practice this actually occurs though). – Jesse Good Sep 19 '12 at 02:46

1 Answers1

2

undefined reference to `operator<<(std::basic_ostream<...>&, XML_AttributeT const&)

That error means that the compiler has parsed the code appropriately and that you have a declaration for the operator with the signature above. But, the linker has not found the definition of that function in your program. This can be caused by different things, like failing to link the library or the .o where the operator is defined.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489