2017-09-17 73 views
0

我有一個相對較小的C++項目,我決定製作一個Utils頭文件,它只包含一些小的輔助函數等。當我聲明使用模板的函數時, ,然後我試圖做一個功能,它不需要模板,突然它不起作用。無法聲明沒有模板的C++函數

我得到的結果是鏈接器錯誤;已經在(文件).obj

定義我甚至不能聲明一個簡單的無效函數,沒有模板的一切都給出了一個鏈接器錯誤。

我沒有任何想法可能導致這種情況。這裏是頭文件的代碼...在此先感謝。

#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; 
    } 
} 
+8

加上'inline'的函數定義在你的頭,要不然移動功能定義到一個單獨的翻譯單元(.cpp文件) 。你不需要'函數模板'的'inline'說明符* – WhiZTiM

+7

提示:模板隱式'inline'。 – Rakete1111

回答

2

一個函數模板隱含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

-2

如果包括你的頭一個以上的CPP,該功能將被定義不止一次和鏈接器會給你上述錯誤。見What is the difference between a definition and a declaration?What are forward declarations in C++?

+1

現在這個答案質量不高。如果您認爲還有其他答案可以回答這個問題,請將問題標記爲重複(或投票結束,當您有足夠的聲望時),請不要回答。如果沒有重複,請在答案中提供解決問題所需的所有信息。現在這個答案並沒有告訴我們如何解決__問題,它只是暗示了原因,請讀者通過其他問題來找到更多的信息。 –