samedi 4 avril 2020

How to include an overloaded operator << from another file in C++? [duplicate]

I want to be able to print the contents of a vector in C++ by using operator overloading.

The operator overloading is defined as follows in the debug.cpp file.

#include <iostream>
#include <vector>

#include "debug.h"
#include "card.h"
#include "player.h"

using namespace std;

template <class T>
ostream &operator<<(ostream &out, const vector<T> &vector)
{
        out << "[";
        for (int i = 0; i < (int)vector.size(); i++) {
                out << vector[i];
                if (i < (int)vector.size() - 1) {
                        out << ",";
                }
        }
        out << "]";
        return out;
}

ostream &operator<<(ostream &out, const Card &card)
{
        out << "[" << card.category << "," << card.players << "]";
        return out;
}

ostream &operator<<(ostream &out, const Player &player)
{
        out << "[" << player.num_cards << "," << player.categories << "]";
        return out;
}

I also have a debug.h file which looks as follows.

#ifndef DEBUG_H
# define DEBUG_H

#include <iostream>
#include <vector>

#include "card.h"
#include "player.h"

using namespace std;

template <class T>
ostream &operator<<(ostream &out, const vector<T> &vector);
ostream &operator<<(ostream &out, const Card &card);
ostream &operator<<(ostream &out, const Player &player);

#endif

This header file is used in my main.cpp file which looks as follows.

#include <iostream>
#include <vector>

#include "debug.h"
#include "card.h"
#include "player.h"

using namespace std;

// Implementation intentially left blank for decluttering.
vector<Card> init_cards(const int &SET_SIZE, const int &NUM_SETS, const int &NUM_PLAYERS)
{

}

// Implementation intentially left blank for decluttering.
vector<Player> init_players(const int &SET_SIZE, const int &NUM_SETS, const int &NUM_PLAYERS)
{

}

int main(int argc, const char **argv)
{
        int SET_SIZE = 4;
        int NUM_SETS = 3;
        int NUM_PLAYERS = 3;

        vector<Card> cards = init_cards(SET_SIZE, NUM_SETS, NUM_PLAYERS);
        vector<Player> players = init_players(SET_SIZE, NUM_SETS, NUM_PLAYERS);

        cout << cards << endl;    // [1]
        cout << players << endl;  // [2]

        return 0;
}

At the complete end of this file there are the lines [1] and [2] which should print the cards and the players vectors. However, this only works if I put the overloading function from the debug.cpp inside of the main.cpp file. The code shown here does not work and gives me the following error.

g++ -Wall -Wextra -Werror -pedantic -std=c++11 -Wno-unused-parameter -I inc -c -o obj/debug.o src/debug.cpp
g++ -Wall -Wextra -Werror -pedantic -std=c++11 -Wno-unused-parameter -I inc -c -o obj/main.o src/main.cpp
g++ -Wall -Wextra -Werror -pedantic -std=c++11 -Wno-unused-parameter -I inc -o quaternity obj/debug.o obj/main.o
/usr/bin/ld: obj/main.o: in function `main':
main.cpp:(.text+0x2b0): undefined reference to `std::ostream& operator<< <Card>(std::ostream&, std::vector<Card, std::allocator<Card> > const&)'
/usr/bin/ld: main.cpp:(.text+0x2d8): undefined reference to `std::ostream& operator<< <Player>(std::ostream&, std::vector<Player, std::allocator<Player> > const&)'
collect2: error: ld returned 1 exit status
make: *** [Makefile:17: quaternity] Error 1

As can be seen the overloaded function cannot be found. How can I make it that the overloaded function will be found?

I already tried to put a namespace std { ... } statement around the declaration of the overloaded function but this did not work. The confusing thing is that all of this does work when I put the overloading functions in the main.cpp file but not when I include them from the debug.cpp file.

Aucun commentaire:

Enregistrer un commentaire