gpt4 book ai didi

c++ - 在 C++ 头文件上检查操作系统时出错

转载 作者:行者123 更新时间:2023-11-28 07:40:06 24 4
gpt4 key购买 nike

我收到了一些 C++ 代码,我正尝试使用提供的 makefile 在 Linux 64 位下编译这些代码。

在该代码中有一个包含代码的 string_hash.h 文件:

#ifndef STRING_HASH
#define STRING_HASH

#include <string>
#include "universal_hash_map.h"

#ifdef WINDOWS
typedef stdext::hash_compare<std::string> String_Hasher;
typedef stdext::hash_map< std::string, std::string, stdext::hash_compare<std::string> > String_Hash;
#else
#ifdef LINUX
class String_Hasher: public stdext::hash< std::string > {
private:
stdext::hash<const char*> hasher;
public:
String_Hasher() {}
size_t operator() (const std::string& p) const {
return hasher(p.c_str());
}
};
typedef stdext::hash_map< std::string, std::string, String_Hasher > String_Hash;
#endif
#endif

#endif

universal_hash_map.h 是:

#include "define_os.h"

#if defined(__MINGW32__) || defined(LINUX)
#include<ext/hash_map>
#define stdext __gnu_cxx;
#else
#if defined(_MSC_VER)
#include<hash_map>
#endif
#endif

和define_os.h:

#if defined(WINDOWS) || defined(LINUX)
#else

#if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) \
|| defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
#define WINDOWS
#elif defined(sun) || defined(__sun) || defined(linux) || defined(__linux) \
|| defined(__linux__) || defined(__CYGWIN__) || defined(BSD) || defined(__FreeBSD__) \
|| defined(__OPENBSD__) || defined(__MACOSX__) || defined(__APPLE__) || defined(sgi) \
|| defined(__sgi)
#define LINUX
#endif

#endif

如果我像那样编译项目,我会收到错误提示编译找不到 stdext::hash

Compiling string_functions.o from /home/adria/Code/JensAdria/trunk/thirdparty/pechin/Cpp_Libraries/mylibrary/codes/string_functions.cpp.
In file included from /home/adria/Code/JensAdria/trunk/thirdparty/pechin/Cpp_Libraries/mylibrary/codes/string_functions.h:5:0,
from /home/adria/Code/JensAdria/trunk/thirdparty/pechin/Cpp_Libraries/mylibrary/codes/string_functions.cpp:1:
/home/adria/Code/JensAdria/trunk/thirdparty/pechin/Cpp_Libraries/mylibrary/codes/string_hash.h:12:29: error: expected class-name before ‘;’ token
/home/adria/Code/JensAdria/trunk/thirdparty/pechin/Cpp_Libraries/mylibrary/codes/string_hash.h:12:29: error: expected ‘{’ before ‘;’ token
/home/adria/Code/JensAdria/trunk/thirdparty/pechin/Cpp_Libraries/mylibrary/codes/string_hash.h:12:35: error: ‘hash’ in namespace ‘::’ does not name a type
/home/adria/Code/JensAdria/trunk/thirdparty/pechin/Cpp_Libraries/mylibrary/codes/string_hash.h:21:9: error: ‘__gnu_cxx’ does not name a type
/home/adria/Code/JensAdria/trunk/thirdparty/pechin/Cpp_Libraries/mylibrary/codes/string_hash.h:21:15: error: ‘hash_map’ in namespace ‘::’ does not name a type
make: *** [string_functions.o] Error 1

但真正让我困惑的是,如果我在 universal_hash_map.h 中注释第一行,使其不包含 define_os.h,代码编译正常!

因此将 universal_hash_map.h 更改为:

//#include "define_os.h"

#if defined(__MINGW32__) || defined(LINUX)
#include<ext/hash_map>
#define stdext __gnu_cxx;
#else
#if defined(_MSC_VER)
#include<hash_map>
#endif
#endif

或者只是

//#include "define_os.h"

//#if defined(__MINGW32__) || defined(LINUX)
#include<ext/hash_map>
#define stdext __gnu_cxx;
//#else
//#if defined(_MSC_VER)
//#include<hash_map>
//#endif
//#endif

编译正常。

但是在最后一个例子中,如果我取消注释 *#include "define_os.h"* 它不会编译 :s

那么问题来了,为什么试图定义操作系统会使代码无法编译?

此外,检查 gcc 预定义符号似乎没有错:

$ gcc -E -dM - </dev/null | grep linux
#define __linux 1
#define __linux__ 1
#define __gnu_linux__ 1
#define linux 1

编辑:关于命名空间的更多信息

在/usr/include/c++/4.7/ext/hash_map(没有文件扩展名)中我有:

#ifndef _BACKWARD_HASH_MAP
#define _BACKWARD_HASH_MAP 1

#ifndef _GLIBCXX_PERMIT_BACKWARD_HASH
#include "backward_warning.h"
#endif

#include <bits/c++config.h>
#include <backward/hashtable.h>
#include <bits/concept_check.h>

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

using std::equal_to;
using std::allocator;
using std::pair;
using std::_Select1st;

/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<class _Key, class _Tp, class _HashFn = hash<_Key>,
class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> >
class hash_map
{
private:
typedef hashtable<pair<const _Key, _Tp>,_Key, _HashFn,
_Select1st<pair<const _Key, _Tp> >,
_EqualKey, _Alloc> _Ht;

_Ht _M_ht;

public:
typedef typename _Ht::key_type key_type;

我似乎无法找到我正在运行的代码的 4.7.3 版本,但是 here是 4.7.2 对我来说似乎是相同的。

编辑:在 string_functions.cpp 上运行 gcc -E 后的文件:

with error (with include)

without Error (without include)

diff

最佳答案

问题是您使用的是非标准类型,因此不能保证它以您的代码所具有的方式具有可移植性。

如果可以(因为你的标准库支持它),你应该切换到 std::unordered_map。它主要是非标准 stdext::hash_map 的标准替代品,无需所有 #ifdefing 即可独立于平台。

要测试它,您可以执行以下操作:

#define stdext std
#define hash_map unordered_map

如果有效,那么我建议快速搜索并替换您的文件。

另一种解决方案是寻找您的 hash_map header 并找出它所在的命名空间。它似乎不在 __gnu_cxx 中。它可能在 stdext 中,它可能被预处理器替换为 __gnu_cxx。

关于c++ - 在 C++ 头文件上检查操作系统时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16014944/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com