跨多个文件的命名空间的“未定义引用”错误

时间:2012-04-13 05:25:28

标签: c++ reference namespaces undefined

我看过几个相关的帖子,但没有运气这个错误。 当我的命名空间存在于多个文件中时,我收到以下未定义的引用错误消息。如果我只编译ConsoleTest.cpp,其中包含转储到其中的Console.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

Console.h

#include <iostream>
#include <sstream>
#include <string>

namespace Console
{
    std::string getLine();

    template <typename T>
    void getValue(T &value);
}

Console.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;
    }
}

ConsoleTest.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;
}

1 个答案:

答案 0 :(得分:2)

模板函数需要在头文件中定义,而不仅仅是声明。编译器需要查看模板实现和模板参数,以在main中构建所需的特化。所以直接将标题放在标题中:

namespace Console
{
    std::string getLine();

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

    }
}