我试图屏蔽一个结构名称,如下所示:
#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/