C++ Template Metaprogramming - Is it possible to output the generated code?

前端 未结 5 1966
臣服心动
臣服心动 2020-12-01 07:58

I would like to debug some templated code to understand it better.
Unfortunately I\'m new to template metaprogramming and it IS hard for me to get in.

When I try

相关标签:
5条回答
  • 2020-12-01 08:23

    This is potentially the answer to your question:

    C++ Template preprocessor tool

    Seems to have satisfied the last person who asked - though I can't imagine why! The output of a C++ compiler in C is usually pretty unreadable, because it isn't intended to be an aid to understanding, merely a kind of portable assembly language.

    0 讨论(0)
  • 2020-12-01 08:24

    No it isn't. The preprocessor has nothing to do with template processing, which is performed by the compiler. Templates do not generate C++ code, any more than a function call does - they are an integral part of the C++ language itself.

    0 讨论(0)
  • 2020-12-01 08:26

    Check my publication on C++ template metaprogram debugging

    From page 6 you can see how it works. For specific purposes you won't need the whole toolchain, it can be done by hand.

    I have put together a Visual C++ add-in where you could place breakpoints etc. but it was rather a proof of concept than a tool for every day use.

    We have been working on a graphical frontend that shows all the instantiations, allows debugging, profiling. Unfortunately we cannot promise any publish date for that tool, as we do it in our quite limited free time.

    UPDATE: the debugger and profiler is available here

    UPDATE: C++Now presentation

    0 讨论(0)
  • 2020-12-01 08:30

    at general it is not possible to output the entire code. But what I found extremely interesting, is the ability to use Visual C++ debugger to show you the type. Take that simple meta-program:

    template<class Head, class Tail>
    struct type_list
    {
      typedef Head head;
      typedef Tail tail;
    };
    
    struct null_type
    {};
    
    template<class List>
    struct list_head
    {
      typedef typename List::head head;
    };
    
    template<class List>
    struct list_tail
    {
      typedef typename List::tail tail;
    };
    
    template<class List>
    struct list_length
    {
      static const size_t length = 1+list_length< typename list_tail<List>::tail >::length;
    };
    
    template<>
    struct list_length<null_type>
    {
      static const size_t length = 0;
    };
    
    
    int main()
    {
      typedef 
        type_list
        < int
        , type_list
          < double
          , type_list
            < char
            , null_type
            >
          >
        >       my_types;
    
      my_types test1;
    
      size_t length=list_length<my_types>::length;
    
      list_head<list_tail<list_tail<my_types>::tail>::tail>::head test2;
    
    }
    

    I just instantiated my meta-types. These are still empty C++ class instances which are at least 1 byte long. Now I can put a breakpoint after the last instantiation of test2 and see, which types/values length, test1 and test2 are of:

    Here is what the debugger shows:

    length  3   unsigned int
    test1   {...}   type_list<int,type_list<double,type_list<char,null_type> > >
    test2   -52 'Ì' char
    

    Now you you know the head returned you a character, your list contains int, double, char and is terminated by null_type.

    That helped me a lot. Sometimes you need to copy the really messy type to a text editor and format it to a readable form, but that gives you the possibility to trace what is inside and how it is calculated.

    Hope that helps,
    Ovanes

    0 讨论(0)
  • 2020-12-01 08:33

    Nope, in general, it can't be done. Templates are simply part of the C++ language, they're not a separate preprocessor, so they don't generate C++ code.

    The usual solution is to sprinkle your code with static asserts and other tests to verify that the right templates get instantiated in the right ways.

    Once you start getting lost in your metaprogramming, this simple trick can help you determine which type a template parameter really is:

    // given a variable t of an unknown type T
    int*** i = t;
    

    When the compiler encounters this, it'll print out a nice and simple error message, "Can not convert <long, detailed typename> to int***", allowing you to easily verify that the template parameter T is actually the type you think it should be.

    0 讨论(0)
提交回复
热议问题