动机
CLI应用程序尝试使用box drawing characters。但是,根据标准输出设备,这可能不合适,因此有一个-t
选项可以使用纯ASCII文本。
该概念只是一个示例,它适用于我们希望在运行时从两组或更多组静态常量中进行选择的任何地方。
问题是什么是干净利落的合理c ++技术。
所需用法语法
这仅是指示性的,但常量“调用”应该简洁
int main(int argc, char* argv[]) {
// using derived class style here, but anything would do
auto t = std::strcmp(argv[1], "-t") == 0 ? TxtTerminal() : BdTerminal();
// here we want the syntax to be short
std::cout << "text" << t.horiz << t.right_t << '\n';
}
已经尝试过
我尝试了基类和派生类样式(如上所述),但是有问题。我不能在TxtTerminal
中放置一组常量,而在BdTerminal
中扩展一组常量(扩展TxtTerminal
)。
struct config { .. };
可能有效map<key,config>
中,并使用吸气剂通过构造函数初始化的bool textmode
成员状态变量来检索适当的常量。 using
别名的某种解决方案。相同的问题。编译时间。而不是运行时。 variable templates
有点像new c++20 maths constants。同样的问题,不是运行时。 [当然,所有这些const
,即“盒式绘图终端”的控制字符的字符串都只是一个字节长。理想情况下,将它们压缩为可执行文件的const char*
(linux)段中的文字初始化的.text
(std::string
似乎有些过分)。无论我们在何处编写这些常量,我们都希望轻松concatenation
以使代码易于读取和维护。使用const char*
字符串文字不是那么容易吗?
[许多选项,似乎没有一个很好。我是否缺少明显的东西?
从评论中,我发现您正在寻找的是:
class Base {
virtual const char* get_config() = 0;
public:
const char* config;
/* other members */
Base(/*arguments*/) : config(get_config()), /*other initializers*/ { }
virtual ~Base() = default;
// methods can use `config` here as pointer
};
struct Derived1 : Base {
using Base::Base;
const char* get_config() override {
static const char[] config{/*...*/};
return config;
}
};
struct Derived2 : Base {
using Base::Base;
const char* get_config() override {
static const char[] config{/*...*/};
return config;
}
};
现在就可以使用派生类型,就像它们的构造函数定义为在Base
中一样,并且所有类中的方法都可以使用config
作为指针,而不会产生任何问题或虚拟调用开销。
或者,如果您想在两种情况之间进行全局切换(即,这些对象的多个实例没有使用不同的配置),那么就根本不需要继承。只需定义一个静态指针,然后让它在两者之间切换即可:
struct Terminal {
static const char config1[]{/*...*/};
static const char config2[]{/*...*/};
static const char* config{};
static void chooseConfig(/*parameters*/) {
config = /*condition*/ ? config1 : config2;
};
// use `config` everywhere
};
int main(int argc, char* argv[]) {
Terminal::chooseConfig(/*arguments*/);
//...
}