我得到的編譯錯誤:C++的內聯函數範圍
Error 7 error C2084: function 'Boolean IsPointInRect(...)' already has a body
在我的內聯函數,該函數聲明如下,以CPP文件:
inline Boolean IsPointInRect(...)
{
...
}
我有完全一樣的功能在另一個cpp文件中。這可能會導致問題?我該如何解決它?
我得到的編譯錯誤:C++的內聯函數範圍
Error 7 error C2084: function 'Boolean IsPointInRect(...)' already has a body
在我的內聯函數,該函數聲明如下,以CPP文件:
inline Boolean IsPointInRect(...)
{
...
}
我有完全一樣的功能在另一個cpp文件中。這可能會導致問題?我該如何解決它?
由於litb和AndreyT指出,這個答案沒有解決實際問題 - 請參閱litbs答案的細節。
雖然static
,如Ofir said,給你內部聯動,「C++方法」是使用未命名空間:
namespace
{
inline Boolean IsPointInRect(/*...*/) { /*...*/ }
}
§7.3.1.1/ 1:
An unnamed-namespace-definition behaves as if it were replaced by
namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }
where all occurrences of unique in a translation unit are replaced by the same identifier and this identifier differs from all other identifiers in the entire program.
§7.3.1.1/ 2補充說:
The use of the static keyword is deprecated when declaring objects in a namespace scope (see annex D); the unnamed-namespace provides a superior alternative.
錯誤 - 這裏有沒有名字的命名空間有什麼用?它們在這裏同樣會失敗:'namespace {inline void a(){}} namespace {inline void a(){}}'(提供主體兩次!),並且它們不會提供任何內聯的「避免」鏈接器錯誤函數(內聯函數可以在程序中定義多次 - 只要在不同的翻譯單元中)。 – 2010-03-04 22:02:10
事實上,現在在VC中測試它 - 感謝修正。對於這個問題的猜測以及對其他答案的反應,這非常重要。我會保留現在的答案以供參考 – 2010-03-04 22:39:25
嗯,爲什麼現在我的答案被接受了?現在有什麼問題? – 2010-03-06 20:31:54
擺脫其中之一?你期望什麼?
也許你應該解釋爲什麼需要兩個版本...
因爲我沒想到內聯函數可以在代碼中隨處訪問。 – clamp 2010-03-04 09:45:08
啊,在這種情況下,你需要「靜態」修飾符,而不是內聯。 – 2010-03-04 17:48:25
或「extern」,如果您只是想聲明函數而不重新定義。 – 2010-03-04 17:48:51
他們將在適當的命名空間,使簡單的解決方案。即使匿名也會工作。
是的,這是舊的「靜態」解決方案的C++替代品。爲什麼這是downvoted? – 2010-03-04 09:58:57
您可以添加「靜態」或「外部」中的「內聯」前,我認爲(我可以使用GCC時知道),例如:
static inline Boolean IsPointInRect(...) { ... }
如果您將它們都變成一個頭應該解決它的文件。或申報其中一個或兩個static
。或者,如果您使用的是MSVC,請將它們聲明爲__declspec(selectany)
。
將您的內聯函數保存在頭文件中,並使用include guard來確保文件不包含兩次。
正如其他人所說,如果你真的想限制的功能cpp文件的範圍,那麼你應該把它放在一個命名空間,例如
namespace // anonymous
{
inline bool IsPointInRect(...)
{
...
}
}
然而,它似乎是一個維護問題,以具有相同體相同的功能(即他們都做同樣的事情)在兩個不同的地方 - 複製/粘貼風格。如果兩種不同的功能具有相同的名稱,但具有不同的主體,那麼這也是等待發生的問題。
顯然你有性能問題(因此內聯),但它最好只有在一個地方寫的功能!至少把它放在一個包含你需要的地方的頭文件(匿名命名空間)中。實際上,您應該「乾淨利落」地完成這項工作,然後只在您的配置文件告訴您時才恢復到性能特定的方法。
乾杯,
Michael
有2種方式聲明內聯函數:
裏面的類:任何函數定義在類內部是一個內聯函數。
課外:如果你在課堂外定義它,那麼你需要使用關鍵字'inline'和函數簽名。
如果你有在不同的類中定義的另一個同名的函數,那麼它將不會,只要您使用範圍解析運算符(拋出任何異常::)和點()與正常對象名稱。
我有完全一樣的功能
你的意思是使用相同的名稱和類型的功能,或者你的意思是使用相同的名稱,類型和身體的功能?後者沒有任何問題,實際上這就是inline
所做的 - 它允許您在不同的翻譯單元中以相同的方式定義相同的功能。對於前者,您必須確保該函數具有文件範圍。 inline
不提供函數文件範圍,static
和未命名的名稱空間都有。一個未命名的命名空間是在C++中使用它的首選方式,至少根據標準:static
已棄用。
1.使用extern和static關鍵字
2.declare它一個名稱空間
裏面你有在這個線程一些錯誤的答案。在你的代碼的問題是,你在你的代碼兩次定義你的內聯函數:
inline Boolean IsPointInRect(...) { ... }
inline Boolean IsPointInRect(...) { ... }
inline
意願,別人說正確的,既保護您不必通過定義兩倍的功能上升錯誤。您不需要static
,也不需要未命名的名稱空間。另請注意,您不應定義其他翻譯單元(處理並擴展所有#include和#if等文件)在.cpp
文件中應使用的內聯函數。他們的定義必須被所有使用它們的翻譯單元所知 - 所以在這種情況下,他們的定義只能在的頭文件中 - 而不是在.cpp
和頭文件中 - 這會導致你得到的錯誤。
您還需要頭部防護,以避免在每個標題
// file foo.h
#ifndef POINTS_H_INCLUDED
#define POINTS_H_INCLUDED
inline Boolean IsPointInRect(...) { ... }
#endif
// file bar.cpp
#include "foo.h"
// does not include the content a second time anymore - the guards aboid it:
#include "foo.h"
和上面的問題,您應該確保不包括一個.cpp
文件到另一個.cpp
文件(.cpp
文件是不應該被包括在內)。您應該將頭文件包含到.cpp
文件中。
@matt:編譯器錯誤的事實使得這個聲音更像是違反了ODR,而不是下面的靜態/名稱空間解決方案將解決的鏈接問題。你在哪裏聲明和IsPointInRect的定義?請在問題中顯示他們。 – quamrana 2010-03-04 10:33:20
@matt:不,問題不是由其他cpp文件中的定義引起的。你在這個翻譯單元中有多個定義。找到他們並修復它。我們無法從這裏看到您的代碼。 – AnT 2010-03-04 22:27:44