没有模板就无法声明c ++函数

时间:2017-09-17 09:44:23

标签: c++ linker-errors

我有一个相对较小的c ++项目,我决定制作一个Utils头文件,它只包含一些小帮助函数等。当我声明使用模板的函数时,一切正常,然后我试图制作一个不需要模板的函数,突然它不起作用。

我得到的结果是链接器错误;已在(文件).obj中定义

我甚至无法声明一个简单的void函数,没有模板的所有内容都会产生链接器错误。

我没有任何想法可能导致这种情况。这是头文件的代码......提前谢谢。

#pragma once

namespace Utils
{
    std::string GetActiveWindowTitle()
    {
        // This doesnt work either, also gives linker error.
        return active_window;
    }

    template<typename T>
    void Print(char * value, T printValue)
    {
        std::cout << value << ": " << printValue << std::endl;
    }

    template<typename T>
    void Print(T printValue)
    {
        std::cout << "DEBUG: " << printValue << std::endl;
    }

    void PrintStr(std::string str)
    {
        // This doesn't work because it doesnt have the template, it gives a linker error
        std::cout << "DEBUG: " << str.c_str() << std::endl;
    }
}

2 个答案:

答案 0 :(得分:2)

function-template 隐式inline。因此,当在头文件中定义时,它不会违反ODR (One Definition Rule)。对于头文件中的非模板函数,您应该将它们定义为inline,或者在单独的翻译单元中定义它们。

所以,你可以这样做:

#pragma once

namespace Utils
{
    inline std::string GetActiveWindowTitle()
    {
        return active_window;
    }

    template<typename T>
    void Print(char * value, T printValue)
    {
        std::cout << value << ": " << printValue << std::endl;
    }

    template<typename T>
    void Print(T printValue)
    {
        std::cout << "DEBUG: " << printValue << std::endl;
    }

    inline void PrintStr(std::string str)
    {
        std::cout << "DEBUG: " << str.c_str() << std::endl;
    }
}

请参阅Inline keyword vs header definition

答案 1 :(得分:-2)

如果将标头包含在多个cpp中,则该函数将被定义多次,链接器将为您提供上述错误。请参阅What is the difference between a definition and a declaration?What are forward declarations in C++?