如何让 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 回答中所描述的那样。
我有一个运行在时间敏感代码中的 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 回答中所描述的那样。