我有一个函数需要不同的库,具体取决于插入其中的值,并且为了防止日志中出现不同的错误消息,我想检查是否包含所需的库,如果不打印错误消息比标准的。
无论如何检查是否包含图书馆?类似的东西:
if(#include <iostream>)
{
//do this
}
修改 的
更多细节....我需要检查库,以便知道我是否可以在我的代码中使用某些变量类型,例如知道我是否可以使用类型字符串或者我应该使用类型char []相反(如果使用cstring库)
答案 0 :(得分:3)
您可以检查是否定义了给定库的特定标头或宏定义。
例如:
#ifdef BOOST_BUILD
#include "somebooststuff.h"
using namespace boost;
#else
#include "somestdstuff.h"
using namespace std;
#endif
其中BOOST_BUILD
是makefile中定义的boost版本。
现在,如果要检查是否包含std::string
的标头,则可以打开此标头并确定其包含的定义。例如,在我的机器标题上
#include <string>
包含:
//
// ISO C++ 14882: 21 Strings library
//
#ifndef _GLIBCXX_STRING
#define _GLIBCXX_STRING 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/stringfwd.h>
#include <bits/char_traits.h> // NB: In turn includes stl_algobase.h
#include <bits/allocator.h>
//...
所以我可以使用以下方法检查std::string
是否已定义:
#ifdef _GLIBCXX_STRING
//do this
#else
// do this
#endif
答案 1 :(得分:2)
不,在C ++中没有这样的构造,似乎借用了PHP。
执行相关操作的一种方法是使用#define
宏静态配置程序,许多GNU和Linux程序也带有config.h
标题。
小例子:
g++ -DHAS_IOSTREAM=1
....
#ifdef HAS_IOSTREAM
#endif
if (HAS_IOSTREAM) {....}
惯例是定义这样的宏,其值不等于零,或者不定义它,因此宏以相对笨拙的方式在所有这些形式中工作:
if (HAS_IOSTREAM) ....
#if HAS_IOSTREAM ....
#ifdef HAS_IOSTREAM ....
#if HAS_IOSTREAM && SOMETHING_ELSE ....
无论如何,在编译之前,您通常必须找到。
另请注意,您不应该依赖包含警卫。我从来没有发现任何明确的提及,但包括守卫是标题本身的实现细节。我似乎在改变,我在重命名文件时会定期更改它们。
答案 2 :(得分:2)
您可以检查预处理器符号的前置。 因为几乎每个头文件(应该)都有一个标题保护,你可以编写例如:
#ifdef Foo_h__
void onlyAvailableIfFooIncluded();
#endif
较大的库通常还定义了一些文件独立符号,如果包含该库的任何标题,则这些符号可用。
答案 3 :(得分:2)
如果您已经控制了相关的头文件,那么您可以执行一些预处理器魔术来执行此操作。
假设您有一个名为 Foo.h 的头文件,请添加:
#define FOO_INCLUDED
进入它。
然后,在您要进行检查的文件中添加以下内容:
#ifdef FOO_INCLUDED
#define FOO_WAS_INCLUDED true
#else
#define FOO_WAS_INCLUDED false
#endif
现在你可以写:
if(FOO_WAS_INCLUDED)
{
// Do this
}
它不漂亮,你会看到一些严厉的外表,但它会起作用!