Language: C++

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <type_traits>
#include <vector>

using namespace std;

static int comp_count = 0;


#ifndef NDEBUG
#define _DBG 1
#include <stdio.h>
#include <stdarg.h>
    void _DbgFunc(char *fn, char *fmt, ...){
        va_list arg; va_start(arg, fmt);
        fprintf(stderr, "%s(", fn);
        vprintf(fmt, arg);
        fputs(")\n", stderr);
        va_end(arg);
    }
#else
#define _DBG 0
#endif

#define DbgP(fmt, ...) \
    do { if (_DBG) fprintf(stderr, fmt, __VA_ARGS__); } while (0)

#define DbgFunc(fmt, ...) \
    do { if (_DBG) _DbgFunc(__FUNCTION__, fmt, __VA_ARGS__); } while (0)

template<typename R, typename A>
void merge(int left, int left_last, int right_last, R ar, A tmp){
    int right = left_last + 1;
    int n = right_last - left + 1;
    int t = left;
    int c = left;
    DbgFunc("%d,%d,%d,%d", left, left_last, right, right_last);

    while (left <= left_last && right <= right_last) {
        if(ar[left] <= ar[right]){
            tmp[t] = ar[left];
            left++;
        }else{
            tmp[t] = ar[right];
            right++;
        }
        t++;
    }

    while (left <= left_last) {
        tmp[t++] = ar[left++];
    }
    while (right <= right_last) {
        tmp[t++] = ar[right++];
    }

    for (int i = 0; i < n; i++) {
        ar[right_last] = tmp[right_last];
        right_last--;
    }

    comp_count += t - c;
}

template<typename R, typename A>
void m_sort(int left, int right, R ar, A tmp){
    if(left < right){
        int mid = (left + right) / 2;
        
        m_sort(left, mid, ar, tmp);
        m_sort(mid + 1, right, ar, tmp);

        merge(left, mid, right, ar, tmp);
    }
}

template<typename T>
void merge_sort(T begin, T end){
    if(begin < end){
        int n = end - begin;
        auto tmp = new typename decay<decltype(*begin)>::type[n];
        m_sort(0, end - begin - 1, begin, tmp);
    }
}

int ar[500000];

int main(int argc, char const* argv[])
{
    int n;

    scanf("%d ", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &ar[i]);
    }

    merge_sort(ar, ar + n);

    for (int i = 0; i < n - 1; i++) {
        printf("%d ", ar[i]);
    }
    printf("%d\n", ar[n - 1]);
    printf("%d\n", comp_count);

    return 0;
}

Compiler output:
a.cc: In instantiation of 'void merge(int, int, int, R, A) [with R = int*; A = int*]':
a.cc:75:14:   required from 'void m_sort(int, int, R, A) [with R = int*; A = int*]'
   75 |         merge(left, mid, right, ar, tmp);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
a.cc:84:15:   required from 'void merge_sort(T, T) [with T = int*]'
   84 |         m_sort(0, end - begin - 1, begin, tmp);
      |         ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.cc:99:15:   required from here
   99 |     merge_sort(ar, ar + n);
      |     ~~~~~~~~~~^~~~~~~~~~~~
a.cc:31:28: error: invalid conversion from 'const char*' to 'char*' [-fpermissive]
   31 |     do { if (_DBG) _DbgFunc(__FUNCTION__, fmt, __VA_ARGS__); } while (0)
      |                    ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                            |
      |                            const char*
a.cc:39:5: note: in expansion of macro 'DbgFunc'
   39 |     DbgFunc("%d,%d,%d,%d", left, left_last, right, right_last);
      |     ^~~~~~~
a.cc:16:25: note:   initializing argument 1 of 'void _DbgFunc(char*, char*, ...)'
   16 |     void _DbgFunc(char *fn, char *fmt, ...){
      |                   ~~~~~~^~
a.cc:39:13: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
   39 |     DbgFunc("%d,%d,%d,%d", left, left_last, right, right_last);
      |             ^~~~~~~~~~~~~
a.cc:31:43: note: in definition of macro 'DbgFunc'
   31 |     do { if (_DBG) _DbgFunc(__FUNCTION__, fmt, __VA_ARGS__); } while (0)
      |                                           ^~~