Can I check which function templates have, or have not, been instantiated at least once?

◇◆丶佛笑我妖孽 提交于 2019-12-10 14:53:50

问题


I have a lot of template code. Since bad template code does not throw a compiler error unless it is compiled, is there any way I can check which template functions the compiler actually 'compiled' and which were ignored altogether?

EDIT 2:

If a particular class template or function template is instantiated once, for any parameter types, then that is OK. I want the list of function/class templates that were never instantiated in any form.

One particular example is the following. They are two distinct template functions, and I would like to know if either or both is never instantiated.

template <typename T_InputItr, typename T_Distance>
void advance( T_InputItr& aItr, T_Distance aN, bidirectional_iterator_tag )

template <typename T_InputItr, typename T_Distance>
void advance( T_InputItr& aItr, T_Distance aN, random_access_iterator_tag )

EDIT: Currently, for classes, I instantiate them in the .cpp file manually like this:

template TClass<int>;

for all the types I am interested in. That's well and good. But that is if I remember to do that. Sometimes I need to write a lot of small template classes/functions where I forget to instantiate some of the function/class templates manually and find out later down the road. I would like the compiler to tell me that.

Alternatively, if I could get the list of function/class templates that were instantiated (for any parameter), then I could compare that to the full list which I might grep for in the code.

Another benefit would be to 'test' which methods were compiled in a template class that uses type traits to selectively compile out certain functions. I want to be certain my logic for selecting the correct functions is correct before moving on.


回答1:


Someone mentioned how "everything can be solved by adding a level of indirection" - you can add a static assert to each function and watch the compilation fail:

template <typename T>
struct Asserter
{
  static const bool value = false;
};

template <typename T>
struct Foo
{
  void foo()
  {
    static_assert(Asserter<T>::value, "Foo::foo() is being compiled.");
  }
  void bar()
  {
    static_assert(Asserter<T>::value, "Foo::bar() is being compiled.");
  }
};

int main()
{
  Foo<int> f;
  //f.foo();  // static assertion!
}

If you don't want compilation to break at each step, you can instead emit a Boost static warning, or something with a similar effect.




回答2:


Given that you are using MSVC 2008, you can do this by generating a linker map file and searching for all the instantiations of that function or inspecting the .pdb via DIA. You'll want to disable COMDAT folding with the linker flag /OPT:NOICF so that you can find functions that happen to compile to the same assembly.




回答3:


You can run your executable through a static analysis tool after compilation provided you have setup your compiler to include the proper symbol tables ... that will show all the instantiated classes along with their template arguments. Here is a link to a list of tools that can be used for static code analysis.



来源:https://stackoverflow.com/questions/8935705/can-i-check-which-function-templates-have-or-have-not-been-instantiated-at-lea

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!