首先,问自己“怎么了我要选择配置,为什么?“ (宏)是无处不在的(你可以将它们定义为编译器标志和代码),但是它们缺少范围限定功能(它们是全局的,不能被定义为名称空间本地),所以它们很容易命名碰撞。
如果是后者你的关心,你可以定义一个特殊的配置类(ES)与类型定义/常量,像这样:
namespace myapp {
struct Config {
class library : library_base { ... }
using other_library = some_other_library;
using version_t = int;
static const version_t VERSION = 1;
}
}
但选择所需的配置,你就必须包括一个多个configXXX.h文件或进行配置类模板,并有多个专业化每个配置,就像这样:
enum class ConfigType {
JPEG, PNG
};
template <ConfigType type> struct Configs;
template <> struct Configs<ConfigType::JPEG> {
using library = libjpeg;
};
template <> struct Configs<ConfigType::PNG> {
using library = libpng;
};
...
static const ConfigType CONFIG_TYPE = ConfigType::JPEG;
...
using Config = Configs<CONFIG_TYPE>;
using library = Config::library;
更新#1:在后面的例子中,组成似乎是最好的解决方案(我已经改名的东西,所以他们做出一点更有意义):
// configs.hpp
enum class AudioType {
MP3, OGG
};
template <AudioType type> struct AudioConfigs;
template <> struct AudioConfigs<AudioType::MP3> {
using Library = libmp3; // of course, you can define class in-place instead of typedef
};
template <> struct AudioConfigs<AudioType::OGG> {
using Library = libvorbis;
};
enum class ImageType {
JPEG, PNG
};
template <ImageType type> struct ImageConfigs;
template <> struct ImageConfigs<ImageType::JPEG> {
using Library = libjpeg;
};
template <> struct ImageConfigs<ImageType::PNG> {
using Library = pnglib;
};
template <AudioType audiotype, ImageType imagetype> struct Configs {
using AudioLibrary = typename AudioConfigs<audiotype>::Library;
using ImageLibrary = typename ImageConfigs<imagetype>::Library;
};
// config_setup.hpp - this one you will edit
#include "configs.hpp"
using Config = Configs<AudioType::MP3, ImageType::JPEG>;
// config.hpp
#include "config_setup.hpp"
using AudioLibrary = typename Config::AudioLibrary;
using ImageLibrary = typename Config::ImageLibrary;
// real code
#include "config.hpp"
AudioLibrary audioLibrary;
audioLibrary.doStuff();
替代结构:
template <AudioType audiotype, ImageType imagetype> struct Configs {
using Audio = typename AudioConfigs<audiotype>;
using Image = typename ImageConfigs<imagetype>;
};
// Options should be accessed like Config::Audio::Library now
更新#2:(只是为了说明无限的可能性),还有一些可变参数模板的魔力,可以缩短AudioConfigs/ImageConfigs /等。到:
template <AudioConfig config> struct AudioConfigs : public LibraryConfigs<AudioConfig, config, AudioType::MP3, AudioType::OGG, libmp3, libvorbis> { };
...完全避免与多个专业的样板代码。然后,您将失去就地定义类的可能性,这就是您在示例中正在做的事情,因此请交叉处理。
downvoter ..请评论,以便我可以改善我的问题。 – w00d
您必须显示示例代码才能显示您希望的目标。有人会最有可能标记你的帖子。 –
确定@NickPavini增加了一个使用宏来做我想要的例子 – w00d