我可以获得正式而非实际模板参数的字符串表示吗?

时间:2016-02-13 21:33:54

标签: c++ templates c++11 reflection

假设我有以下内容:

class Foo { };
template <typename T> class Bar { };
template <typename NiftyType> class Baz { };

在现代(ish)C ++中,我可以使用:

typeid(Foo).name()  // to will produce "Foo", or
typeid(Bar<int>).name() // to produce "Bar<int>"

但最后一行给出了实际的模板参数;我想要正式的。也就是说,我希望能够说:

magic<Bar<int>>(); // to produce "Bar<typename T>" or just "T", and
magic<Baz<int>>(); // to produce "Bar<typename Nifty>" or just "Nifty"

我能以某种方式这样做吗?

(明显)注意:

  • 请不仅仅是课程。
  • 我无法检测类型(如果您对此要求感到不满,则认为它不是我的代码)。但是,我认为,某种混合类的部分解决方案是可以接受的......
  • 我不想手动将相应的字符串写入某个地图。

1 个答案:

答案 0 :(得分:1)

怎么样

actorID = h[:actorID]

然后你可以像这样定义class Foo { }; template <typename T> class Bar { static const char * debug_name() { return "Bar<typename T>"; } }; template <typename NiftyType> class Baz { static const char * debug_name() { return "Baz<typename NiftyType>"; } };

magic

并按照您的意愿使用它

template <typename T>
struct magic {
  operator const char * () { return T::debug_name(); }
};

我认为,基于我的C ++经验,要求编译器为您生成int main() { magic<Bar<int>>(); magic<Baz<int>>(); } 是非常有希望的。 C ++是一种很好用且有用的语言,但内省绝对不是它的强项,你要求内省一个模板,而不仅仅是一个类型。

请注意,如果编译器被强制支持您要求的内置内容,它会有效地禁止编译器解析模板定义并丢弃模板参数的(不相关的)标识符名称,并仅存储已解析的模板定义的AST形式,它可能希望这样做以减少内存使用量。或者它可能需要对源进行第二次传递以再次获取名称或者可怕的东西。

我觉得有一些远不如你所要求的那些不可能的东西,或者只是使用各种编译器特定扩展的东西。 HTH