一些语言包含表达不可变符号的构造。例如,Ruby符号文字的格式为::symbolName
。然后,例如,可以使用它们来有效地从地图(error_count[:syntax_errors]
)中检索值,而且它们可以容易地转换为字符串(:syntax_error.to_s
)。我的经验是,它创建了非常易读和可维护的代码。
C ++中是否有类似的东西(我不想使用整数常量,因为我需要声明它们并且它们不能轻易转换为字符串;我不想运行脚本我的源文件在编译之前做了一些奇特的替换)?我正在寻找使用C预处理器的解决方案或元模板编程的一些技巧。
答案 0 :(得分:4)
有一个std :: unordered_map<>在C ++ 11中,但是因为你在谈论"符号文字"你可以用静态符号更好地做到这一点。简单的方法是直接C和C预处理器。
#define declare_literal(x) const char x[] = #x
declare_literal(foo); //now "foo" is a global symbol you can use everywhere
这并不能提供您可能正在寻找的单一实例保证。这实际上比人们希望的更难实现,但你可以用一些丑陋的方式来实现:
template <typename CharType, CharType... args>
struct symbol_base {
using self_type = symbol<CharType, args...>;
static constexpr std::size_t char_length = sizeof...(args) / sizeof(CharType);
static constexpr CharType value[char_length] = {CharType(args)...};
static const std::string& as_string() { static const std::basic_string<CharType> val{value, char_length}; return val; }
operator const std::string&() const { return as_string(); }
};
template <char... args>
using symbol = symbol_base<char, args...>;
template <wchar_t... args>
using wsymbol = symbol_base<wchar_t, args...>;
那么你可以为&#34; foo&#34;做一个符号。用:
symbol<'f', 'o', 'o'> foo;
不完全优雅,但有效。
答案 1 :(得分:2)
C ++中没有symbols,因为编译时和运行时是不同的世界。
然而,您可以播放一些预处理器技巧(请参阅X_macros)。请参阅this,this等...
所以你可能有一个文件定义你的符号,例如。
// file my-symbols.def
MY_SYMBOL(a)
MY_SYMBOL(foo)
#undef MY_SYMBOL
你会多次使用它,例如曾经宣布一些枚举:
enum my_symbols_en {
#define MY_SYMBOL(N) sy_##N,
#include "my-symbols.def"
};
如果你不喜欢enum
- s使用类似的技巧来声明不同的东西,例如静态实例......
一次,例如定义输出例程
std::ostream& operator <<(std::ostream& out, my_symbols_en symb) {
switch (symb) {
#define MY_SYMBOL(Sy) case sy_##N: out << #Sy ; break;
#include "my-symbols.def"
default: std::cerr << "bad symbol" << std::endl; exit(EXIT_FAILURE);
}
return out;
}
同样适用于输入,散列,字符串转换等...
您还可以在构建框架中使用专门的C ++生成脚本。例如,某些my-symbols.def
脚本可能会生成awk
...
答案 2 :(得分:0)