Вызовите перегруженный оператор для структуры, определенной в том же пространстве имен, что и класс в методе класса - PullRequest
1 голос
/ 06 апреля 2019

У меня есть структура coord, определенная в пространстве имен saw. В том же пространстве имен я также перегрузил operator<< для coord. В методе buildSAW() SAWBuilder я успешно создаю coord, но когда я пытаюсь использовать перегруженный <<, я получаю Undefined symbols for architecture x86_64:, когда пытаюсь скомпилировать. Программа может успешно компилироваться, однако, когда я использую std::out << coord.toString() << std::endl. Как я могу успешно получить доступ к перегруженной operator<< для coord в методе для SAWBuilder?

// saw.hpp    
#ifndef __SAW_HPP__
#define __SAW_HPP__

#include <iostream>
#include <sstream>
#include <string>

using std::string;
using std::ostream;

namespace saw
{

    class SAWBuilder
    {
    public:
        SAWBuilder() {}

        int buildSAW() const;

        static const int SIZE_M = 100;

    };

    struct coord
    {
        int x;
        int y;
        int z;

        string toString();
    };

    ostream& operator<<(ostream& os, const coord& c);

}

#endif

Файл реализации:

// saw.cpp
#include "saw.hpp"

#include <iostream>
#include <sstream>
#include <string>

using std::string;
using std::ostringstream;

using std::endl;

namespace saw
{
    int SAWBuilder::buildSAW() const
    {
        int visited[SIZE_M][SIZE_M][SIZE_M] = {}; // initalize to zero

        coord starting_coord = coord{SIZE_M/2, SIZE_M/2, SIZE_M/2};

        std::cout << visited[0][0][0] << std::endl;

        std::cout << starting_coord << std::endl; // <- problem here!

        return 0;
    }

    string coord::toString()
    {
        ostringstream out;

        out << "[" << x << ", " << y << ", " << z << "]";

        return out.str();
    }

    ostream& operator<<(ostream& os, coord& c)
    {
        os << c.toString();
        return os;
    }

} 

Основной файл:

// main.cpp    
#include "saw.hpp"

using saw::SAWBuilder;

int main(int argc, char **argv)
{
    SAWBuilder saw;

    int a = saw.buildSAW();

    return a;
}

Makefile:

CXX = g++
CXXFLAGS = -Wall -pedantic -std=c++17 -g

Saw: main.o saw.o
    ${CXX} ${CXXFLAGS} -o $@ $^

main.o: saw.hpp
saw.o: saw.hpp

1 Ответ

2 голосов
/ 06 апреля 2019
ostream& operator<<(ostream& os, const coord& c);

объявлено, но вместо него определено

ostream& operator<<(ostream& os, coord& c)

, что делает его другой функцией.Обратите внимание на отсутствующие const.Я бы проголосовал за закрытие как опечатку, если бы не

os << c.toString();

, для которой требуется coord::toString, чтобы быть константной функцией, и, вероятно, причина того, что пропущенный const отсутствует: const -скомпилировано меньше версий, что заставляет спрашивающего думать, что это правильно.

Таким образом, в дополнение к

ostream& operator<<(ostream& os, const coord& c) // added const
{
    os << c.toString();
    return os;
}

коду также требуется

struct coord
{
    int x;
    int y;
    int z;

    string toString() const; // added const
};

и более поздняя реализация

string coord::toString() const // added const
{
    ostringstream out;

    out << "[" << x << ", " << y << ", " << z << "]";

    return out.str();
}
...