C++尝试将命名空间放在单独文件中时出现未定义符号。

huangapple go评论62阅读模式
英文:

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:
  &quot;Huffman::operator&lt;&lt;(std::__1::basic_ostream&lt;char, std::__1::char_traits&lt;char&gt; &gt;&amp;, Huffman::EncodingMap const&amp;)&quot;, referenced from:
      _main in main-4994c4.o
ld: symbol(s) not found for architecture arm64
// huffman.cpp
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;queue&gt;
#include &lt;unordered_map&gt;
#include &lt;memory&gt;

namespace Huffman
{
  struct TreeNode
  {
  private:
    struct Compare
    {
      bool operator()(std::shared_ptr&lt;TreeNode&gt; left, std::shared_ptr&lt;TreeNode&gt; right)
      {
        return left-&gt;frequency &gt; right-&gt;frequency;
      }
    };

  public:
    char symbol;
    unsigned frequency;
    std::shared_ptr&lt;TreeNode&gt; left;
    std::shared_ptr&lt;TreeNode&gt; right;

    TreeNode(char symbol, unsigned frequency)
        : symbol(symbol), frequency(frequency) {}

    static std::shared_ptr&lt;TreeNode&gt; buildTree(const std::string &amp;text)
    {
      std::unordered_map&lt;char, unsigned&gt; frequencyTable;
      for (char c : text)
      {
        ++frequencyTable[c];
      }

      std::priority_queue&lt;std::shared_ptr&lt;TreeNode&gt;, std::vector&lt;std::shared_ptr&lt;TreeNode&gt;&gt;, Compare&gt; queue;

      for (const auto &amp;[symbol, frequency] : frequencyTable)
      {
        queue.push(std::make_shared&lt;TreeNode&gt;(symbol, frequency));
      }

      while (queue.size() &gt; 1)
      {
        auto left = queue.top();
        queue.pop();

        auto right = queue.top();
        queue.pop();

        auto newNode = std::make_shared&lt;TreeNode&gt;(&#39;$&#39;, left-&gt;frequency + right-&gt;frequency);
        newNode-&gt;left = left;
        newNode-&gt;right = right;

        queue.push(newNode);
      }

      return queue.top();
    }
  };

  class EncodingMap
  {
  private:
    std::unordered_map&lt;char, std::string&gt; map;

    void build(std::shared_ptr&lt;Huffman::TreeNode&gt; node, std::string code)
    {
      if (node.get() == nullptr)
        return;

      if (node-&gt;left == nullptr &amp;&amp; node-&gt;right == nullptr)
      {
        map[node-&gt;symbol] = code;
        return;
      }

      build(node-&gt;left, code + &quot;0&quot;);
      build(node-&gt;right, code + &quot;1&quot;);
    }

  public:
    EncodingMap(const std::string &amp;text)
    {
      auto root = TreeNode::buildTree(text);
      build(root, &quot;&quot;);
    }

    friend std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, const EncodingMap &amp;map)
    {
      for (auto &amp;&amp;[key, value] : map.map)
      {
        std::cout &lt;&lt; key &lt;&lt; &quot;=&quot; &lt;&lt; value &lt;&lt; std::endl;
      }
      return os;
    }

    const std::string &amp;operator[](char symbol)
    {
      return map[symbol];
    }
  };

  std::pair&lt;std::string, EncodingMap&gt; encode(const std::string &amp;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 &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;queue&gt;
#include &lt;unordered_map&gt;
#include &lt;memory&gt;

namespace Huffman
{
  struct TreeNode
  {
  public:
    char symbol;
    unsigned frequency;
    std::shared_ptr&lt;TreeNode&gt; left;
    std::shared_ptr&lt;TreeNode&gt; right;

    TreeNode(char symbol, unsigned frequency)
        : symbol(symbol), frequency(frequency) {}

    static std::shared_ptr&lt;TreeNode&gt; buildTree(const std::string &amp;text);
  };

  class EncodingMap
  {
  public:
    EncodingMap(const std::string &amp;text);

    friend std::ostream &amp;operator&lt;&lt;(std::ostream &amp;os, const EncodingMap &amp;map);

    const std::string &amp;operator[](char symbol);
  };

  std::pair&lt;std::string, EncodingMap&gt; encode(const std::string &amp;text);
};

#endif
// main.cpp
#include &lt;iostream&gt;
#include &quot;./huffman.hpp&quot;

int main()
{
  auto [encoded, map] = Huffman::encode(&quot;hello world&quot;);
  std::cout &lt;&lt; encoded &lt;&lt; std::endl;
  std::cout &lt;&lt; map &lt;&lt; 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 &quot;x.h&quot;
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 &quot;x.h&quot;
void X::f()
{
// code here
}

huangapple
  • 本文由 发表于 2023年5月17日 17:25:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76270535.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定