如何让 MyClass 的用户控制通过编译器标志实例化 class 的哪个版本?

How to let users of MyClass, control which version of the class is instantiated by means of a compiler flag?

我有一个运行在时间敏感代码中的 C++ class,这样仅仅构建对象就可能比用户花费更多的时间。我想定义我的 class 的标准版本和可简单构造的版本,并让 class 的用户控制通过编译器实例化哪个版本的 class旗帜。我希望编译器标志在 group 级别工作。例如,如果标志是 LEVEL=:OFF,GROUP1:ON,那么将为 class 的所有实例构造平凡版本,除了 GROUP1 中的那些实例,这将获得实际的、非平凡的实例化。目标是让用户能够在编译时通过更改标志值来关闭某些组。

我想使用 C++11 的 std::conditional 来控制使用哪个版本的 class。为此,我需要检查与 class 的给定用法相关联的组,并将其与该组的编译器标志设置进行比较。我想不出 class 的用户将编译时设置从用户的源文件传递给主 class 定义的方法。我可以要求用户在他们的源文件中放置类似 #define MYCLASS_GROUP ON 的内容,但我认为我不能在定义我的 class 的文件中引用它。

class 的用户是否可以通过用户的源文件控制 class 的编译版本?在此先感谢您的任何想法!

更新:以下是我理想中的使用方式。用户可以做:

#define MYCLASS_GROUP GROUP1

MyClass myClassInstance;

然后,他们可以通过编译器标志控制实例化哪个版本。因此 -DMYCLASS_GROUP_LEVEL=:OFF,GROUP1:ON 将在 GROUP1.

中启用上述用例

在 class 定义中,我想要类似于以下无效伪代码的内容:

class MyClassOn {
  non-trivial code here
};
class MyClassOff {
};
typedef std::conditional<check-group-here, MyClassOn, MyClassOff>::type MyClass;

您可以使用模板专业化。

首先声明选项:

class DefaultVersion;
class TriviallyConstructible;

接下来创建 class

的主模板定义
template <typename T = DefaultVersion>
class MyClass;

默认版本的专业化:

template< >
class MyClass< DefaultVersion >
{
    // ...
};

可简单构建版本的专业化

template<>
class MyClass< TriviallyConstructible >
{
    // ...
};

用法示例

MyClass<> m1;
MyClass< DefaultVersion > m2; // same as m1
MyClass< TriviallyConstructible > m3;

如果用户愿意,他们可以为这种类型声明一个别名,可以在应用程序中使用。


如何将编译时标志传递给class?

通过预处理器指令和别名。

#ifdef GROUP1 > 0
using MyClassGroup1 = MyClass< TriviallyConstructible >;
#else
using MyClassGroup1 = MyClass< DefaultVersion >;
#endif

或另一种方式:

#ifdef GROUP1 > 0
using Group1 = TriviallyConstructible;
#else
using Group1 = DefaultVersion;
#endif

并在使用地点

MyClass< Group1 > m4;
#define MYCLASS_GROUP GROUP1
MyClass myClassInstance;

不起作用。通常,如果您需要通过预处理器调整 lib 代码,您可以在包含 lib header.

之前定义标识符
#define MYCLASS_GROUP GROUP1
#include <MyClass.h>

MyClass myClassInstance;

MyClass.h 中,您只需检查定义的内容。

在您的特定情况下,您不需要预处理器,正如 Robert Andrzejuk 回答中所描述的那样。