#include <iostream>

template < int... Ints >
struct int_list { };

template < char... Chars >
struct char_list { };

template < int N, int... Ints >
struct make_int_list_impl : make_int_list_impl< N-1, N-1, Ints... >
{ };

template < int... Ints >
struct make_int_list_impl< 0, Ints... > {
    using type = int_list< Ints... >; 
};

template < int N >
using make_int_list = typename make_int_list_impl< N >::type;

inline bool and_all() { return true; }

template < typename First, typename... Args >
inline bool and_all( First first, Args... args ) {
    return first && and_all( args... );
}

template < char... Chars >
void print( char const * str, char_list< Chars... > chars ) {
    print_impl( str, chars, make_int_list< sizeof...(Chars) >() );
}

template < char... Chars, int... Ints >
void print_impl( char const * str, char_list< Chars... >, int_list< Ints... > ) {
    if( and_all( (str[Ints] == Chars)... ) )
        std::cout << str << std::endl;
}

int main() {
    
    auto prefix = char_list<'a','a','b'>();
    
    char const* strs[] = {
        "aabfghfghfhfhghfgjdj"
        , "abafgjfgjfgjfgjfgjfe"
        , "abbklhfhfhdfhhroryor"
        , "aabqeprtpeteptpedmfd"
        , "aabeererpedpfgpdfgpd"
        , "abbrrrtrterterkhjkhj"
    };
    
    for( auto const * str : strs )
        print( str, prefix );
}