C ++内联函数的范围

时间:2010-03-04 09:40:47

标签: c++ inline

我收到了编译错误:

  

错误7错误C2084:function'布尔值   IsPointInRect(...)'已经有一个正文

在我的内联函数中,在cpp文件中声明如下:

inline Boolean IsPointInRect(...) 
{
...
}

我在另一个cpp文件中具有完全相同的功能。可能这会导致问题吗?我怎么解决呢?

11 个答案:

答案 0 :(得分:14)

正如litb和AndreyT指出的那样,这个答案并没有解决实际问题 - 详见litbs答案。


虽然staticOfir said,为您提供内部链接,但“C ++方式”是使用未命名的命名空间:

namespace
{
     inline Boolean IsPointInRect(/*...*/) { /*...*/ }
}

§7.3.1.1/ 1

  

unnamed-namespace-definition的行为就像它被

替换一样
 namespace unique { /* empty body */ }
 using namespace unique; 
 namespace unique { namespace-body }
  

其中翻译单元中所有出现的唯一标识都被相同的标识符替换,并且此标识符与整个程序中的所有其他标识符不同。

§7.3.1.1/ 2 添加:

  

在声明命名空间范围内的对象时,不推荐使用static关键字(参见附件D); unnamed-namespace提供了一个更好的选择。

答案 1 :(得分:10)

你在这个帖子中得到了一些错误的答案。您的代码中的问题是您在代码中定义了两次内联函数:

inline Boolean IsPointInRect(...) { ... }   
inline Boolean IsPointInRect(...) { ... }
正如其他人所说的那样,

inline已经通过定义两次函数来保护您免于错误。您不需要static,也不需要未命名的命名空间。另请注意,您不应该定义内联函数,这些内联函数应该被{{>中的其他翻译单元(所有#include和#if等...都被处理和扩展的文件)使用1}}文件。所有使用它们的翻译单元都必须知道它们的定义 - 所以在这种情况下将它们的定义放在头文件中 - 而不是在.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文件中。

答案 2 :(得分:6)

将它们放入适当的命名空间可以提供简单的解决方案即使是匿名者也会工作。

答案 3 :(得分:3)

正如其他人所说,如果你真的想将函数的范围限制在cpp文件中,那么你应该把它放在命名空间中,例如

namespace // anonymous
{
    inline bool IsPointInRect(...)
    {
        ...
    }
}

然而,在两个不同的地方(复制/粘贴样式)对同一个主体(即它们都做同样的事情)具有相同的功能似乎是一个维护问题。如果两个不同的函数具有相同的名称但具有不同的主体,那么这也是一个等待发生的问题。

显然你有性能问题(因此内联),但最好只将函数写在一个地方!至少将它放在头文件(在匿名命名空间中)中,该文件包含在您需要的位置。实际上,您应该“干净利落地”执行此操作,然后在您的探查器告诉您时,仅恢复特定于性能的方法。

干杯,

Michael

答案 4 :(得分:2)

如果将它们都移动到应该解决它的单个头文件中。或者声明其中一个或两个static。或者,如果您使用的是MSVC,请声明它们__declspec(selectany)

答案 5 :(得分:1)

将内联函数保存在头文件中,并使用include guard来确保文件不包含两次。

答案 6 :(得分:1)

我有完全相同的功能

您是指具有相同名称和类型的函数,还是指具有相同名称,类型和正文的函数?后者没有任何问题,实际上这就是inline的作用 - 它允许您在不同的翻译单元中以相同的方式定义相同的功能。对于前者,您必须确保该函数具有文件范围。 inline不提供函数文件范围,static和未命名的命名空间都可以。未命名的命名空间是在C ++中执行它的首选方式,至少根据标准:static已弃用。

答案 7 :(得分:0)

摆脱其中一个?你有什么期望?

也许您应该解释为什么需要两个版本......

答案 8 :(得分:0)

您可以在“内联”前面添加“静态”或“外部”我认为(我知道您可以在使用GCC时),例如:

static inline Boolean IsPointInRect(...) { ... }

答案 9 :(得分:0)

有两种声明内联函数的方法:

  1. 在类中:在类中定义的任何函数都是内联函数。

  2. 课外:如果你在课外定义,那么你需要使用关键字'inline'和函数签名。

  3. 如果您在另一个类中定义了另一个具有相同名称的函数,那么只要您正确使用范围解析运算符(::)和点(。)与对象名称,它就不会抛出任何异常。

答案 10 :(得分:0)

1.使用extern和static关键字

2.声明它在命名空间