一点背景:我想编写一个工具,将一堆命名的东西编译成C++代码.列表发生变化,我不希望在发生这种情况时重建世界.尽管如此,我想通过(文字)名称来解决编译的代码.
作为一个不太正确的事情的例子,我可以把它放在标题中:
template<int name> void func();
Run Code Online (Sandbox Code Playgroud)
然后我的工具可以生成如下代码:
template<> void func<1>() { ... }
template<> void func<2>() { ... }
template<> void func<3>() { ... }
Run Code Online (Sandbox Code Playgroud)
现在我可以在任何地方用"名字"来称呼它们而不预先声明每一个.
我想这样做,但有一些比整数更具描述性的东西.理想情况下,我想要某种形式的文本.我需要的是:
#define FUNC_WITH_NAME(name) func_named_ ## name
Run Code Online (Sandbox Code Playgroud)
但这并不完全有效:它需要声明func_named_whatever.
下一次尝试也不好(并且它是特定于GCC的):
#define FUNC_WITH_NAME(name) ({extern void func_named_ ## name; func_named_ ## name;})
Run Code Online (Sandbox Code Playgroud)
它失败了,因为如果它在命名空间中使用,那么它最终会在该命名空间中查找func_named_whatever .
我想出的最好的是:
template<char... tagchars> int tagged();
namespace NS {
int caller()
{
return tagged<'n', 'a', 'm', 'e'>();
}
}
Run Code Online (Sandbox Code Playgroud)
这是有效的,但它很难看(如果不跳过令人讨厌的篮球,如何将字符串文字转换为参数包并不明显).此外,如果符号没有解析,那么来自g ++的错误消息很糟糕:
In function `NS::caller()':
named_symbol.cpp:(.text+0x5): undefined reference to `int tagged<(char)110, (char)97, …Run Code Online (Sandbox Code Playgroud)