gpt4 book ai didi

c++ - 覆盖运算符<<时的友元问题

转载 作者:行者123 更新时间:2023-11-30 00:39:45 25 4
gpt4 key购买 nike

我正在尝试重载 operator<<以标准方式。我有一个名为 SymbolTable 的类,位于名为 SymbolTable.h 的文件中,如下所示:

namespace Compaler // It's a pun; don't ask
{

class SymbolTable
{
public:
// ...
friend ostream& operator<<(ostream &out, const SymbolTable &table);
private:
vector<map<int, Symbol*> > mSymbols;
};

// ...

}

执行operator<<访问 SymbolTable 的一些私有(private)成员。这是实现的签名,以证明它与前向声明的签名没有区别(我复制粘贴它以确保我没有发疯。)

ostream& operator<<(ostream &out, const SymbolTable &table)
{ ... }

如果我将实现放在第二个 ... 所在的 SymbolTable.h 中,我会收到以下链接器错误:

ld: duplicate symbol Compaler::operator<<(std::basic_ostream >&, Compaler::SymbolTable const&)in /var/folders/kt/pl6qd1490fn3yqxfpg64jyr80000gn/T//ccstrYnU.o and /var/folders/kt/pl6qd1490fn3yqxfpg64jyr80000gn/T//ccDQFiyK.o for architecture x86_64

但是,如果我把它放在 SymbolTable.cpp 中,我的 SymbolTable 成员实现的其余部分所在的位置,代码甚至无法编译;我收到与访问私有(private)成员相关的错误,表明未识别友元:

../SymbolTable/SymbolTable.h: In function ‘std::ostream& operator<<(std::ostream&, const Compaler::SymbolTable&)’: ../SymbolTable/SymbolTable.h:75: error: ‘std::vector, std::allocator >, Compaler::Symbol*, std::less, std::allocator > >, std::allocator, std::allocator >, Compaler::Symbol*> > >, std::allocator, std::allocator >, Compaler::Symbol*, std::less, std::allocator > >, std::allocator, std::allocator >, Compaler::Symbol*> > > > > Compaler::SymbolTable::mSymbols’ is private ../SymbolTable/SymbolTable.cpp:98: error: within this context

我做错了什么?

答案总结:

感谢 Seth Carnegie 和 Daniel R. Hicks,我已经弄明白了。为了将来可能会犯同样错误的任何人的利益,我将总结我的问题中的答案,因为评论中有很多来回。

第一个(在 SymbolTable.h 中实现时出现重复符号)问题是因为我试图同时编译和链接两个包含 SymbolTable.h 的文件。我一直在误会下如何工作#ifdef包括 guard 工作;也就是说,它们只会阻止代码在一个文件中被包含两次,但如果您尝试链接两个都包含来自第三方的代码的文件,它们将无济于事。

第二个问题是我忘了把我的 operator<<当我在 SymbolTable.cpp 文件中有它时,它在 Compaler 命名空间中实现。

最佳答案

如果你在头文件中这样做你需要使用内联:

namespace Compaler // It's a pun; don't ask
{
class SymbolTable
{
public:
friend ostream& operator<<(ostream &out, const SymbolTable &table);
private:
vector<map<int, Symbol*> > mSymbols;
};

inline ostream& operator<<(ostream &out, const SymbolTable &table)
{
out << table[0].something;
return out;
}
}

如果你想在源文件中做。然后运算符<<必须在命名空间中声明

标题.h

namespace Compaler // It's a pun; don't ask
{
class SymbolTable
{
public:
friend ostream& operator<<(ostream &out, const SymbolTable &table);
private:
vector<map<int, Symbol*> > mSymbols;
};
ostream& operator<<(ostream &out, const SymbolTable &table);
}

源代码.cpp

#include "Header.h"
namespace Compaler // must be here
{
ostream& operator<<(ostream &out, const SymbolTable &table)
{
out << table[0].something;
return out;
}
}

关于c++ - 覆盖运算符<<时的友元问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8024798/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com