c++中的符号数据类型

Symbol datatype in C++

本文关键字:数据类型 符号 c++      更新时间:2023-10-16

一些语言包含表达不可变符号的结构。例如,在Ruby中,符号文字的形式是::symbolName。然后,例如,可以使用它们来有效地从映射(error_count[:syntax_errors])中检索值,而且它们可以很容易地转换为字符串(:syntax_error.to_s)。我的经验是,这创建了非常易读和可维护的代码。

在c++中是否有类似的东西(我不想使用整数常量,因为我需要声明它们,它们不能轻易转换为字符串;我不想在编译之前在我的源文件上运行脚本,这做了一些花哨的替换)?我正在寻找使用C预处理器或从元模板编程的一些技巧的解决方案。

在c++ 11中有一个std::unordered_map<>,但由于您谈论的是"符号字面量",实际上使用静态符号可以更好地完成此操作。最简单的方法是直接使用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...>;

那么你可以为foo创建一个符号:

symbol<'f', 'o', 'o'> foo;

不是很优雅,但是很有效。

c++中没有符号,因为编译时和运行时是两个不同的世界。

但是,您可以使用一些预处理器技巧(参见X_macros)。看这个,这个,等等…

你可能有一个文件来定义你的符号,比如

 // file my-symbols.def
 MY_SYMBOL(a)
 MY_SYMBOL(foo)
 #undef MY_SYMBOL

,你会多次使用它,例如一次声明一些enum:

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脚本生成的…

enum构造就是为此而构建的。

使用枚举的一些好例子

如果需要散列映射,请考虑std::unordered_map

c++中的简单hashmap实现