'LLDB customize print of template class

I use LLDB as my debugger, and want it to print my template class MyArray<N> in a customized format.

I read the LLDB document, and come up with python script that can get public and private data members of MyArray<N>. However, I don't know how to get N (the template parameter), neither do I know how to get result return by MyArray<N>::size().

Here is the code

#include <stdio.h>
#include <iostream>

template<int N>
class MyArray
{
public:
    MyArray(){data = new int[N];}
    ~MyArray(){if (data) delete[] data;}

    int size() const{ return N;}
    int& operator[](size_t i) { return data[i];}
    int const& operator[](size_t i) const { return data[i];}

private:
    int* data = nullptr;
};

template<int N>
std::ostream& operator <<(std::ostream& os, const MyArray<N>& arr)
{
    os << "N = " << arr.size() << std::endl;
    os << "elements in array:" << std::endl;
    for (int i = 0; i < arr.size(); i++) {
        if (i > 0) os << ", ";
        os << arr[i];
    }
    return os << std::endl;
}

int main()
{
    MyArray<10> arr;
    for (int i = 0; i < arr.size(); i++)
        arr[i] = 10 + i;
    std::cout << arr << std::endl;  // Yeah, I can use this for print. but I want this during LLDB debug

    return 0;
}

//// Update: Add corresponding lldb config ~/.lldbinit:

command script import ~/.lldbcfg/print_my_array.py

~/.lldbcfg/print_my_array.py:

def print_my_array(valobj, internal_dict):
    #N = valobj.GetChildMemberWithName("size") # failed
    N = 10
    data = valobj.GetChildMemberWithName("data")
    info = ''
    for i in range(N):
        if(i>0): info += ', '
        info += str(data.GetChildAtIndex(i).GetValueAsSigned(0))
    info += ')'
    return info

def __lldb_init_module(debugger, internal_dict):
    debugger.HandleCommand('type summary add -P MyArray<10> -F ' + __name__ + '.print_my_array')


Solution 1:[1]

The simple way would be to store the value of N as static member:

template<int N>
class MyArray
{
public:
    static constexpr const int n = N;
};

Supposed MyArray is not your type you can infer the template argument via a trait:

template <typename T>
struct get_value;

template <int N>
struct get_value<MyArray<N>> {
     static constexpr const n = N;
};

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 463035818_is_not_a_number