1

我看过几个相关的帖子,但没有遇到这个错误。当我的命名空间存在于多个文件中时,我会在下面收到此未定义的引用错误消息。如果我只编译 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

控制台.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;
}
4

1 回答 1

2

模板函数需要在头文件中定义,而不仅仅是声明。编译器需要查看模板实现和模板参数以在 main.xml 中构建您需要的专业化。所以直接把定义放在头部:

namespace Console
{
    std::string getLine();

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

    }
}
于 2012-04-13T05:28:35.993 回答