跨多个文件的命名空间"undefined reference"错误

"undefined reference" error with namespace across multiple files

本文关键字:undefined reference 错误 命名空间 文件      更新时间:2023-10-16

我看了几个相关的帖子,但这个错误没有运气。当我的命名空间存在于多个文件中时,我在下面收到此未定义的引用错误消息。如果我只编译 ConsoleTest.cpp使用控制台的内容.cpp将源代码编译到其中。

我将不胜感激有关此问题的任何反馈,提前感谢您。

g++ Console.cpp ConsoleTest.cpp  -o ConsoleTest.o -Wall
/tmp/cc8KfSLh.o: In function `getValueTest()':
 ConsoleTest.cpp:(.text+0x132): undefined reference to `void Console::getValue<unsigned int>(unsigned int&)'
collect2: ld returned 1 exit status

控制台.h

#include <iostream>
#include <sstream>
#include <string>
namespace Console
{
    std::string getLine();
    template <typename T>
    void getValue(T &value);
}

控制台.cpp

#include "Console.h"
using namespace std;
namespace Console
{
    string getLine()
    {
        string str;
        while (true)
        {
            cin.clear();
            if (cin.eof()) {
                break;  // handle eof (Ctrl-D) gracefully
            }
            if (cin.good()) {
                char next = cin.get();
                if (next == 'n')
                    break;
                str += next;    // add character to string
            } else {
                cin.clear(); // clear error state
                string badToken;
                cin >> badToken;
                cerr << "Bad input encountered: " << badToken << endl;
            }
        }
        return str;
    }               

    template <typename T>
    void getValue(T &value)
    {
        string inputStr = Console::getLine();
        istringstream strStream(inputStr);
        strStream >> value;
    }
}

控制台测试.cpp

#include "Console.h"
void getLineTest()
{
    std::string str;
    std::cout << "getLinetest" << std::endl;
    while (str != "next")
    {
        str = Console::getLine();
        std::cout << "<string>" << str << "</string>"<< std::endl;
    }
}
void getValueTest()
{
    std::cout << "getValueTest" << std::endl;
    unsigned x = 0;
    while (x != 12345)
    {
        Console::getValue(x);
        std::cout << "x: " << x << std::endl;
    }
}
int main()
{
    getLineTest();
    getValueTest();
    return 0;
}

模板函数需要在标头中定义,而不仅仅是声明。编译器需要查看模板实现和模板参数,以构建主服务器所需的专用化。所以直接把定义放在标题中:

namespace Console
{
    std::string getLine();
    template <typename T>
    inline void getValue(T &value) {
        string inputStr = Console::getLine();
        istringstream strStream(inputStr);
        strStream >> value;
    }
}