【问题标题】:How to 'rename' a template instantiation without using inheritance?如何在不使用继承的情况下“重命名”模板实例化?
【发布时间】:2013-12-26 07:43:23
【问题描述】:

假设您在应用程序中使用模板类,例如std::tuple (或 std::shared_ptr 或其他),并且您有这样的实例化:

typedef std::tuple<Book,Library> BookLibrary;
typedef std::tuple<Book,Chapter,Reader> BookChapterReader;

然后您在其他模板类中使用这些实例化,例如作为类成员的 std::map:

class X
   {
   ...
   private:
      std::map<Library,BookChapterReader> m_data;
   };

然后生成的 PDB 文件将包含如下描述(使用 Microsoft 调试工具的 DBH 实用程序查看):

std::_Tree<std::_Tmap_traits<Library,std::tr1::tuple<Book,Chapter,Reader,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil>,std::less<Library>,std::allocator<std::pair<Library const ,std::tr1::tuple<Book,Chapter,Reader,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil> > >,0> >

如果你有很多这样的结构,那么 PDB 文件会增长得很快,直到链接器拒绝链接你的应用程序(显然,PDB 文件有 1 GB 的限制)。

一种解决方案可能是创建模板化实例的子类,如下所示:

class BookChapterReader : public std::tuple<Book,Chapter,Reader>
   {
   };

这将严重缩短符号。现在上面提到的是:

std::_Tree<std::_Tmap_traits<Library,BookChapterReader,std::less<Library>,std::allocator<std::pair<Library const ,BookChapterReader> >,0> >

但是,通过使用继承,我们引入了可能向继承的类添加数据的风险,并且我们可能需要引入一个虚拟析构函数(在这种情况下我不想要它)。

看来C++(或者Visual Studio?)有一个限制:

  • 如果我只使用 typedef,符号会变得太大
  • 如果我使用继承,我似乎想扩展 std::tuple,但我不想这样做

难道没有一种更简洁的方法可以在不使用继承的情况下“重命名”模板实例化吗?

【问题讨论】:

  • 我不认为VS2010支持它,我也不知道它是如何处理PDB“扩展”的,否则你可以尝试例如using BookChapterReader = std::tuple&lt;Book, Chapter, Reader&gt;;
  • 一个类型需要有一个唯一的名字,所以不同的 TU 知道他们在谈论同一个东西。因此,缩短调试符号的唯一机会是创建新的/不同的类型(注意 typedef/using 只会创建别名)。
  • @JoachimPileborg using X = foo;equivalenttypedef foo X;,所以差异会令人惊讶(但尝试并确实看到并不需要太多成本)。 @Patrick 顺便说一句,让你的问题变得更糟的是 VS2010 没有真正支持 C++11 并使用“std::tr1::tuple&lt;Book,Chapter,Reader,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil,std::tr1::_Nil&gt;”来表示真正应该简单的“std::tuple&lt;Book,Chapter,Reader&gt;”(我认为 VS2012 或更高版本确实如此)用途)。但这不是答案,我知道...
  • @gx_,我知道。 VS2010 的实现甚至被限制在 10 个维度。这就是我使用 boost::fusion::vector 而不是 std::tuple 的原因,但我想让这个例子足够简单。

标签: c++ visual-studio-2010 templates pdb-files


【解决方案1】:

创建您自己的 lessallocator 实现版本,而不是依赖名称很长的默认版本。

std::map< Library, BookChapterReader, CompareLibrary, MyAllocator > m_data;

分配器类非常简单,比较函子也是如此。

【讨论】:

  • std::less&lt;Library&gt; 是 18 个字符。 CompareLibrary 是 14。差别不大。
  • @PlasmaHH:您忘记了应该将自定义类放在命名空间中;所以你至少在看X::Y
  • @MatthieuM.:它也应该有一个像样的名字,所以放弃命名空间的要求并缩短内容。
  • 分配器很长,由于某种原因,第二个模板参数类型没有使用 typedef。
  • @PlasmaHH:老实说,我唯一能想到的就是放弃 MSVC,直到它们实现对类型的体面支持,例如......在 PDB 的开头使用 type -&gt; id 映射并且仅之后引用id 的类型?
猜你喜欢
  • 1970-01-01
  • 2018-09-13
  • 1970-01-01
  • 2022-08-19
  • 2015-12-18
  • 1970-01-01
  • 2017-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多