英文:
C++ Undefined symbols when I try to put namespace in a separate file
问题
I have a problem with putting namespaces in separate files. Everything works for me when I write everything in one file, but when I try to create cpp+hpp files, that's where it all starts. Maybe I'm doing something wrong in the header file or linking the files incorrectly? I really don't know. I will be very grateful for your help.
Here is my error. On 86x_64 it also throws it out, but without mentioning the architecture:
Undefined symbols for architecture arm64:
"Huffman::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Huffman::EncodingMap const&)", referenced from:
_main in main-4994c4.o
ld: symbol(s) not found for architecture arm64
// huffman.cpp
#include <iostream>
#include <string>
#include <queue>
#include <unordered_map>
#include <memory>
namespace Huffman
{
// ... (code omitted for brevity)
};
// huffman.hpp
#ifndef HUFFMAN_H
#define HUFFMAN_H
#include <iostream>
#include <string>
#include <queue>
#include <unordered_map>
#include <memory>
namespace Huffman
{
// ... (code omitted for brevity)
};
#endif
// main.cpp
#include <iostream>
#include "./huffman.hpp"
int main()
{
auto [encoded, map] = Huffman::encode("hello world");
std::cout << encoded << std::endl;
std::cout << map << std::endl;
return 0;
}
I tried to build it with cmake, but I also built it myself for testing, and the error is really independent of my build system:
g++ ./src/main.cpp ./src/huffman.cpp -std=c++17
Is there anything specific you'd like to know or discuss regarding this code?
英文:
I have a problem with putting namespaces in separate files. Everything works for me when I write everything in one file, but when I try to create cpp+hpp files, that's where it all starts. Maybe I'm doing something wrong in the headerfile or linking the files incorrectly? I really don't know. I will be very grateful for your help.
Here is my error. On 86x_64 it also throws it out, but without mentioning the architecture
Undefined symbols for architecture arm64:
"Huffman::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Huffman::EncodingMap const&)", referenced from:
_main in main-4994c4.o
ld: symbol(s) not found for architecture arm64
// huffman.cpp
#include <iostream>
#include <string>
#include <queue>
#include <unordered_map>
#include <memory>
namespace Huffman
{
struct TreeNode
{
private:
struct Compare
{
bool operator()(std::shared_ptr<TreeNode> left, std::shared_ptr<TreeNode> right)
{
return left->frequency > right->frequency;
}
};
public:
char symbol;
unsigned frequency;
std::shared_ptr<TreeNode> left;
std::shared_ptr<TreeNode> right;
TreeNode(char symbol, unsigned frequency)
: symbol(symbol), frequency(frequency) {}
static std::shared_ptr<TreeNode> buildTree(const std::string &text)
{
std::unordered_map<char, unsigned> frequencyTable;
for (char c : text)
{
++frequencyTable[c];
}
std::priority_queue<std::shared_ptr<TreeNode>, std::vector<std::shared_ptr<TreeNode>>, Compare> queue;
for (const auto &[symbol, frequency] : frequencyTable)
{
queue.push(std::make_shared<TreeNode>(symbol, frequency));
}
while (queue.size() > 1)
{
auto left = queue.top();
queue.pop();
auto right = queue.top();
queue.pop();
auto newNode = std::make_shared<TreeNode>('$', left->frequency + right->frequency);
newNode->left = left;
newNode->right = right;
queue.push(newNode);
}
return queue.top();
}
};
class EncodingMap
{
private:
std::unordered_map<char, std::string> map;
void build(std::shared_ptr<Huffman::TreeNode> node, std::string code)
{
if (node.get() == nullptr)
return;
if (node->left == nullptr && node->right == nullptr)
{
map[node->symbol] = code;
return;
}
build(node->left, code + "0");
build(node->right, code + "1");
}
public:
EncodingMap(const std::string &text)
{
auto root = TreeNode::buildTree(text);
build(root, "");
}
friend std::ostream &operator<<(std::ostream &os, const EncodingMap &map)
{
for (auto &&[key, value] : map.map)
{
std::cout << key << "=" << value << std::endl;
}
return os;
}
const std::string &operator[](char symbol)
{
return map[symbol];
}
};
std::pair<std::string, EncodingMap> encode(const std::string &text)
{
EncodingMap map = EncodingMap(text);
std::string encodedText;
for (char c : text)
{
encodedText += map[c];
}
return std::make_pair(encodedText, map);
}
};
// huffman.hpp
#ifndef HUFFMAN_H
#define HUFFMAN_H
#include <iostream>
#include <string>
#include <queue>
#include <unordered_map>
#include <memory>
namespace Huffman
{
struct TreeNode
{
public:
char symbol;
unsigned frequency;
std::shared_ptr<TreeNode> left;
std::shared_ptr<TreeNode> right;
TreeNode(char symbol, unsigned frequency)
: symbol(symbol), frequency(frequency) {}
static std::shared_ptr<TreeNode> buildTree(const std::string &text);
};
class EncodingMap
{
public:
EncodingMap(const std::string &text);
friend std::ostream &operator<<(std::ostream &os, const EncodingMap &map);
const std::string &operator[](char symbol);
};
std::pair<std::string, EncodingMap> encode(const std::string &text);
};
#endif
// main.cpp
#include <iostream>
#include "./huffman.hpp"
int main()
{
auto [encoded, map] = Huffman::encode("hello world");
std::cout << encoded << std::endl;
std::cout << map << std::endl;
return 0;
}
I tried to build it with cmake, but I also built it myself for testing, and the error is really independent of my build system.
g++ ./src/main.cpp ./src/huffman.cpp -std=c++17
答案1
得分: 2
这就是你应该将类拆分为头文件和源文件的方式。
// 头文件,x.h
#ifndef X_H
#define X_H
class X
{
void f();
};
#endif
// 源文件,x.cpp
#include "x.h"
void X::f()
{
// 此处编写代码
}
英文:
This is how you are supposed to split classes into header file and source files
// header file, x.h
#ifndef X_H
#define X_H
class X
{
void f();
};
#endif
// source file, x.cpp
#include "x.h"
void X::f()
{
// code here
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论