c++ - 掩蔽结构名称

标签 c++ visual-c++ c++17

我试图屏蔽一个结构名称,如下所示:

#define cat_val(l, r) l##r
#define name_mask cat_val(exception_, __COUNTER__)

using i_dont_show_in_rtti = struct name_mask
{
// ...
};

void test()
{
    throw i_dont_show_in_rtti{};
}
这有效,但只能在文件中单独使用。如果我包含已完成此操作的文件,则会出现命名冲突(因为 __COUNTER__ 每个文件都会重置)。
我的其他选择是什么?有没有另一种方法可以改变一个名称,使其难以理解但又独一无二,而不会使我的代码变得异常丑陋?

最佳答案

可以在完全标准的 C++14 中做到这一点。

  #include <cstdlib>

  template <std::size_t N>
  constexpr std::size_t ct_hash(const char (&str)[N])
  {
      std::size_t hash = 0;
      for (std::size_t i = 0; i < N; ++i)
          hash = (hash << 7) + (str[i] * str[i]); // just an example
      return hash;
  }

  template <std::size_t ... hashes>
  struct mangled;


  // don't have to use all of these, it's just an example. may use __COUNTER__ instead of __LINE__.
  #define HIDE_STRUCT(S) \
  using S = struct mangled<ct_hash(__FILE__), __LINE__, ct_hash(__DATE__), ct_hash(__TIME__), ct_hash(#S)>; \
  template <> struct mangled<ct_hash(__FILE__), __LINE__, ct_hash(__DATE__), ct_hash(__TIME__), ct_hash(#S)>

  HIDE_STRUCT(foo)
  {
      int a;
  };

  HIDE_STRUCT(bar)
  {
      int a; char b;
  };

  void test()
  {
      throw foo{};
  }

  void test2()
  {
      throw bar{};
  }
如果您担心可能的散列冲突,您可以可逆地加密您的字符串而不是散列它们,但这可能需要 C++20 宽松的非类型模板参数(以便您可以对加密的字符串进行参数化)。您将不得不编写一个编译时加密函数。

关于c++ - 掩蔽结构名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62825984/

相关文章:

C++ STL :map search by iterator to another map

c++ - 这段代码如何找到 float 的符号

multithreading - 如何知道代码是在 ui 线程还是工作线程上运行 (MFC Visual C++)

windows - win32 API SearchPath 失败

c++ - 如何改变MFC PropertySheet的字体

c++ - 将 lambda 包装为 std::function 会产生错误的结果(是模板参数推导的危险)

c++ - C++14 中 char 类型下限的变化是否会破坏与补码系统的兼容性?

c++ - 在这种情况下使用 cin 是正确的功能吗?

c++ - std::invoke 和 std::apply 有什么区别?

c++ - 高效可变参数等于任何函数