C++ 如何解决头文件中的变量冲突?

C++ 如何解决头文件中的变量冲突?,c++,visual-studio-2017,C++,Visual Studio 2017,我正在OpenSees(一个主要在visual studio c++中编写的开源地震工程模拟项目)中编写一个自适应步长更新算法。我在两个不同的头文件(即windef.h和steelz01.h)中遇到两个同名变量之间的冲突。我需要一个解决这场冲突的方法 我在我的项目中使用gnuplot iostream.h,只有当我包含这个头文件时,我才会面临这种冲突,否则就没有冲突,代码构建得非常完美 基本上,gnuplot iostream.h调用windows.h,后者进一步调用windef.h。我在ste

我正在OpenSees(一个主要在visual studio c++中编写的开源地震工程模拟项目)中编写一个自适应步长更新算法。我在两个不同的头文件(即windef.h和steelz01.h)中遇到两个同名变量之间的冲突。我需要一个解决这场冲突的方法

我在我的项目中使用gnuplot iostream.h,只有当我包含这个头文件时,我才会面临这种冲突,否则就没有冲突,代码构建得非常完美

基本上,gnuplot iostream.h调用windows.h,后者进一步调用windef.h。我在steelz01.h文件中添加了include gauards,但它并没有解决这个问题

当我将steelz01.h中的varaibale名称更改为另一个名称时,代码也可以完美构建。没有发现问题。但是,我不想更改steelz01中变量的名称,它会产生严重的影响

我包括这样的头文件

#include "gnuplot-iostream.h"
#include <SteelZ01.h>
typedef struct tagSIZE
{
    LONG        cx;
    LONG        cy;
} SIZE, *PSIZE, *LPSIZE;

typedef SIZE               SIZEL;
typedef SIZE               *PSIZEL, *LPSIZEL;
在windef.h中,它的定义如下

#include "gnuplot-iostream.h"
#include <SteelZ01.h>
typedef struct tagSIZE
{
    LONG        cx;
    LONG        cy;
} SIZE, *PSIZE, *LPSIZE;

typedef SIZE               SIZEL;
typedef SIZE               *PSIZEL, *LPSIZEL;
Visual Studio 2017正在抛出此错误

1>c:\program files (x86)\windows kits\8.1\include\shared\windef.h(190): error C2378: 'SIZE': redefinition; symbol cannot be overloaded with a typedef

1>e:\phd working folder\0_ops_github\src\material\nd\reinforcedconcreteplanestress\steelz01.h(17): note: see declaration of 'SIZE'

我希望有一种方法可以解决此冲突并成功构建。

我建议您将include语句放在名称空间中

namespace ABC
{
    #include "gnuplot-iostream.h"
}

namespace PQR
{
   #include <SteelZ01.h>
}

这不会更改现有库的任何代码。然而,使用公共名称的库的作者因此建议他将公共名称保留在名称空间下,以减少任何冲突。

为什么首先需要变量
SIZE
?为什么不能使用宏?更好的是,用一个合适的常量变量替换宏。导出名为just
SIZE
的变量是一个严重的问题。这是一个糟糕的设计,其他程序员后来不得不与之斗争。C++解决方案-使用<代码>命名空间SyrZ01 0。不要使用<代码>定义< <代码>,使用<代码>静态CONTXPROP>代码>。,steelz01的作者就是这样定义的。我可以更改
大小的定义,但问题是我必须更改steelz01所有继承项中的变量名,然后您应该将其作为错误报告给项目的作者。
#define
与其说是一个错误,不如说是一个应该避免的错误。
#define
>导致在编译器开始编译之前进行简单的文本替换。只要代码中存在
LOOP\u NUM\u LIMIT
,它就会被无意识地替换为38。我认为这一个相当安全,但它是不必要的。这很有趣。我将在命名空间中实现头文件,并让您知道这一点。谢谢这确实假设头提供了所有内容的完整定义(例如,在单独的源文件中没有函数,例如,可能作为单独的对象文件或库提供,并且程序不会与此方法链接).No头文件只包含声明。我有一个单独的.cpp文件,其中包含所有成员函数定义。此命名空间方法有任何问题吗?这将分别处理定义和声明。我不认为这会产生问题。这是一个非常糟糕的主意。如果它编译,它会告诉编译器所有名称在该头文件中声明的名称将在该命名空间中定义。但是定义这些名称的源文件对该命名空间一无所知,其定义肯定不会在其中。不要对编译器撒谎。如果这是“仅头文件”,则是的库中定义了所有内联函数,然后它可以编译和链接。但结果是,在该标头中定义的每个函数都有两个版本,一个在命名空间中,另一个不在命名空间中。祝您调试顺利。