2011-06-08 66 views
6

如果两个不同的库定义相同的枚举会发生什么,我需要在同一个项目中使用两个库?冲突的枚举

枚举月{1月= 0,2月,...,12月}

谢谢。

P.S.它是C.没有名称空间。我将无法将他们分开。需要一些解决方法。

什么是枚举链接?内部还是外部? C++项目中使用的C库。 C++标签适用。

+2

希望两个库使用单独的名称空间? – GWW 2011-06-08 22:10:47

+4

这对于类型,变量或函数的多个冲突定义确实没有什么不同。 – 2011-06-08 22:12:45

+1

这是C还是C++?他们不是一种语言。 – 2011-06-08 22:15:34

回答

5

终极魔法邪恶的巫师解决方法:如果命名空间不帮忙(无论何种原因),你绝对不能避免包括在同一个文件中定义,使用宏:

#define Month File_A_Month 
#include "file_a.h" 
#define Month File_B_Month 
#include "file_b.h" 
#undef Month 

在文件中,请勿使用Month,只能使用File_A_MonthFile_B_Month。我不确定这种做法的标准是否正确。

您可能必须同样定义所有枚举成员以防止冲突,并且您可能希望将此恶作剧放入名为files_a_and_b.h的文件中。当然,在你的情况下,定义是相同的,所以你不应该诉诸于此,但我将这个答案留给不幸的后代。

+0

+1,没有想到这一点。 – 2011-06-08 22:27:15

+1

+1。这是邪恶的,但我会尽量小心。 – pic11 2011-06-08 22:52:50

+0

即使定义相同,相同的枚举常量名称也会导致名称冲突。但是,正如前面提到的那样,对每个枚举名应用宏hack将会起到一定作用。 – 2011-06-08 23:24:42

11

在C++项目中使用的C库。 C++标签适用

因为他们是在C++项目中使用,那么你可以让他们参与C++代码时使用的命名空间:

// C files 
//libone.h 
enum Month {January=0, February, ..., December} 

//libtwo.h 
enum Month {January=0, February, ..., December} 

/////////////////////////////////////////////////////////////////// 
//C++ files 

//lib.hpp 
namespace LibOne 
{ 
    #include "libone.h" 
} 
namespace LibTwo 
{ 
    #include "libtwo.h" 
} 

//Usage in C++ 
LibOne::Month m1 = LibOne::January; 
LibTwo::Month m2 = LibTwo::January; 
+0

+1。但是我有太多的代码已经使用lib_1。 – pic11 2011-06-08 22:46:35

+0

@ pic11:我不知道你的代码结构如何。但有一点可以肯定的是,无论何时向导致名称冲突的C++项目添加新库时,都可以将新库包含在不同的名称空间中。 – Nawaz 2011-06-08 22:49:36

+0

我正在编写C++ API,并且在我的lib的命名空间中已经定义了相同的枚举。用户代码可以将枚举值传递给我的API,然后API将相同的值传递给C API。 – pic11 2011-06-08 23:06:19

2

理想的情况下,两者在不同的命名空间。

否则,您可能可以避免将两个定义都包含在一个编译单元中。

编辑:好的,你在C中,所以你没有命名空间,这听起来像你想在同一个编译单元中引用两个定义。下一步:

  • 他们有完全相同的定义吗?
  • 您是否对任何一个库中的名称有影响?
  • 你确定你不能在其他编译单元中隐藏对其中之一的引用吗?
+0

定义相同。 – pic11 2011-06-08 22:25:12

+4

@pic:如果定义相同,则应该没有问题。 – 2011-06-08 22:29:55

+0

@Oli。是的,只要两个库中的定义不包含在同一个翻译单元中,就没有问题。 – pic11 2011-06-08 22:47:52

4

无论是enum本身也不枚举常量的对象,所以他们没有任何联系的话 - 在这方面,他们就像struct标签或typedef名称。

这意味着你有两种解决方法:

  • 确保冲突的报头是从来没有直接或间接地,以相同的翻译单元(.c文件)#include d;或
  • 推销一个或两个标题以更改冲突的名称。

头洗钱可以做到通过创建头与名称的私有副本改变,或使用预处理器为Chris Lutz's answer

+0

+1。 Quote:*确保冲突头永远不会,直接或间接,包括在同一个翻译单位* – pic11 2011-06-08 23:07:19

0

Quote:我正在编写C++ API和相同的枚举已经在我的lib的命名空间中定义。

所以这些枚举之一是在你的库的命名空间内?那么你应该没有问题。你使用的C库在全局命名空间中,你的库有自己的命名空间,只要你做的是正确的事情,两者永远不会发生冲突。以下是完全有效的,我相信:

extern "C" { 
    #include "foo.h" 
    // enum Month { January, February, December }; 
} 

namespace mylib { 
    enum Month { Chaos, Discord, Confusion, Bureaucracy, Aftermath }; 

    Month convert(::Month c_month); 
} 

void foo() { 
    ::Month month = December; 
    mylib::Month result = mylib::convert(month); 
}