Как писал Evg , у него старый вопрос с правильным ответом.
#ifndef CRTP_VARIADIC_FRIEND
// M - Macro
// N - Number
// P - Packed parameters
// T - Type
# define CRTP_FRIEND_REPEAT_2(M, N, P, T) M(N, P, T) M(N + 1, P, T)
# define CRTP_FRIEND_REPEAT_4(M, N, P, T) CRTP_FRIEND_REPEAT_2(M, N, P, T) CRTP_FRIEND_REPEAT_2(M, N + 2, P, T)
# define CRTP_FRIEND_REPEAT_8(M, N, P, T) CRTP_FRIEND_REPEAT_4(M, N, P, T) CRTP_FRIEND_REPEAT_4(M, N + 4, P, T)
# define CRTP_FRIEND_REPEAT_16(M, N, P, T) CRTP_FRIEND_REPEAT_8(M, N, P, T) CRTP_FRIEND_REPEAT_8(M, N + 8, P, T)
# define CRTP_FRIEND_REPEAT_32(M, N, P, T) CRTP_FRIEND_REPEAT_16(M, N, P, T) CRTP_FRIEND_REPEAT_16(M, N + 16, P, T)
# define CRTP_FRIEND_REPEAT_64(M, N, P, T) CRTP_FRIEND_REPEAT_32(M, N, P, T) CRTP_FRIEND_REPEAT_32(M, N + 32, P, T)
# define CRTP_FRIEND_REPEAT_128(M, N, P, T) CRTP_FRIEND_REPEAT_64(M, N, P, T) CRTP_FRIEND_REPEAT_64(M, N + 64, P, T)
# define CRTP_FRIEND(N, P, T) \
friend std::tuple_element_t<std::min(static_cast<std::size_t>(N + 1), sizeof...(P)), std::tuple<void, T...>>;
# define CRTP_VARIADIC_FRIEND(P, T) CRTP_FRIEND_REPEAT_128(CRTP_FRIEND, 0, P, T)
#endif
Я попробую решение класса Trait. Это будет другой ответ позже.
Пример выполнения