【发布时间】:2021-11-23 10:34:30
【问题描述】:
我正在编写一些库,并希望有一些“可选”类方法(或只是函数),无论是否声明,都取决于其他库包含。
说,我有一个类SomeClass,方法是int foo(std::string)。有时,使用项目所基于的另一个库的类的类似方法也非常有用 - 例如,sf::String 或 wxString,相应地用于 SFML 或 wxWidgets。
在这种情况下,包括SFML/System.hpp 或更糟,wx/app.hpp 或类似的绝对是不一个选项,因为我只想拥有已经的库的方法> 包括在内。因此,我的第一个示例必须(如我所想)可以正常工作,但事实并非如此:
main.cpp:
#include <SFML/System.hpp> // FIRST, I include SFML base lib in the very first line.
#include <SFML/System/String.hpp>// to be 100% sure, I include SFML string class,
#include "a.h" // and ONLY AFTER that I include my own lib
// so inside the "a.h" file, the sf::String class *must* be already declared
main()
{ SomeClass x;
x.foo("ABC");// error here: "undefined reference to `SomeClass::foo(sf::String)"
}
啊哈:
#ifndef A_H_INCLUDED
#define A_H_INCLUDED
class SomeClass
{ public:
#ifdef SFML_STRING_HPP
int foo(sf::String str);// this method is declared, as expected
#endif
};
#endif
a.cpp:
#include "a.h"
#ifdef SFML_STRING_HPP
int SomeClass::foo(sf::String str)
{ return 1;
}
#endif
第一个问题是:为什么? a.cpp 一开始就包含a.h,而在a.h 内部,sf::String 是 声明的,那么为什么在a.cpp 之后 #include "a.h" 它实际上没有声明?
我尝试在a.cpp 文件中的#endif 指令之前添加#error OK,但此错误未被触发。
我是否错过了有关 #include 和 .cpp / .h 文件的内容?...
第二个问题是:如何解决或解决这个问题?
(是的,我每次都进行干净的重建以避免可能的编译器错误,因为部分更改源代码,g++ 喜欢它)。
P.S:相同类型的“依赖”方法声明与某些模板类完美配合 - 我想,这是因为实现在 .h 文件中,条件编译一切正常。
【问题讨论】:
-
一点提示:您可以通过将
#include语句放入预处理器#ifdef范围内来使它们成为可选语句。因此,您可以在声明和定义使用它的函数的相同条件下包含字符串头。 -
根据上下文变化的类定义迟早会咬你。不要那样做。
-
皮特,它为什么会咬人?我声明并定义了不同的 方法,所以在基于SFML 的项目中我将使用
fooSM(sf::String),在基于wxWidgets 的项目中我将使用fooWX(wxString)方法。这使我可以为许多不同的项目保持主库代码相同,并且还避免过多的类型转换(根据项目的基础库使用本机类型)。
标签: c++ include conditional-compilation