为在与类方法中的类相同的命名空间中定义的结构调用重载运算符

Call overloaded operator for struct defined in same namespace as class in class method

本文关键字:定义 结构 调用 运算符 重载 命名空间 类方法      更新时间:2023-10-16

我在命名空间saw中定义了一个结构coord。在同一个命名空间中,我还重载了coordoperator<<。在buildSAW()方法SAWBuilder中,我成功地创建了一个coord但是当我尝试使用重载<<时,当我尝试编译时会Undefined symbols for architecture x86_64:。该程序能够成功编译,但是当我使用std::out << coord.toString() << std::endl时。如何在 for SAWBuilder 方法中成功访问重载的operator<< coord

// 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
ostream& operator<<(ostream& os, const coord& c);

已声明,但

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

而是定义,使其成为不同的函数。请注意缺少的const 。如果不是因为,我会投票关闭为错字

os << c.toString();

这要求coord::toString是一个 const 函数,并且可能是缺少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();
}