问题描述
我正在围绕一个框架编写一个软件,并且我正在使用的类(准确地说,是扩展类)在以后的版本中已重命名。有什么方法可以在C ++ 11中编写一些宏/模板,以确定是否在代码中声明了具有特定名称的类?
I am writing a piece of software around a framework and a class I am using (to be precise, extending) was renamed in a later version. Is there some way to write some macros/templates in C++11 in order to determine if a class with a certain name had been declared at the point in code?
下面是我要完成的任务的说明。
假设文件class_include.h包含类 A
的定义:
An illustration of what I'm trying to accomplish follows.Let's say that file class_include.h contains either the definition of class A
:
class A
{
...
};
或类 B
:
class B
{
...
};
和类 C
尝试扩展那些声明为:
and class C
tries to extend whichever of those is declared:
#include <class_include.h>
#if (class A is declared)
class C : public A
#else // class B is declared
class C : public B
#endif
{
...
};
注意:我想尝试检查框架的版本,但是答案是问题使我感兴趣。我也不能更改任何框架头文件。
Note: It came to my mind to try and check a version of the framework but the answer to this question interests me. I also cannot change any framework header files.
编辑:可接受的答案取决于是否定义了类(这意味着声明),并且在我的情况下,如果定义了该类,则声明该类。
The accepted answer depends on whether the class is defined (which implies declaration) and, in my case, the class is declared iff it's defined.
推荐答案
可以,并且不需要宏。首先观察一下,即使可以使用完整的定义,也可以转发声明一个类。即这是有效的:
You can, and with no macros required. First an observation, you can "forward" declare a class even after its full definition is available. I.e. this is valid:
class foo{};
class foo;
现在,借助自制的 void_t
实现和 is_complete
类型的实用程序,您可以执行以下操作:
Now, with the help of a homebrew void_t
implementation and an is_complete
type utility, you can do something like this:
#include <type_traits>
template<typename... Ts> struct make_void { typedef void type;};
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
template <typename T, typename Enabler = void>
struct is_complete : std::false_type {};
template <typename T>
struct is_complete<T, ::void_t<decltype(sizeof(T) != 0)>> : std::true_type {};
class A;
class B;
class C : public std::conditional<is_complete<A>::value, A, B>::type {
};
取决于 A 存在,
C
将从 A
或 B 公开。 。
Depending on whether or not the full definition of
A
is present, C
will inherit from A
or B
publicly. See a live example.
但是我告诫,这需要谨慎处理,否则您的程序中很可能会违反ODR。
But I caution, this needs to be handled with care or you are very likely to have an ODR-violation in your program.
这篇关于如何检查是否在C ++中声明了一个类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!