¿Es 0 un literal decimal o un literal octal?

¿Es 0 un literal decimal o un literal octal?

Sí, 0 es un literal octal en C++.

Según el estándar C++:

2.14.2 Literales enteros [lex.icon]

integer-literal:  
    decimal-literal integer-suffixopt  
    octal-literal integer-suffixopt  
    hexadecimal-literal integer-suffixopt  
decimal-literal:  
    nonzero-digit  
    decimal-literal digit  
octal-literal:  
    0                           <--------------------<Here>
    octal-literal octal-digit

Cualquier valor entero con el prefijo 0 es un valor octal. Es decir:01 es 1 octal, 010 es 10 octal, que es 8 decimal, y 0 es 0 octal (que es decimal, y cualquier otro, 0).

Así que sí, '0' es un octal.

Esa es la traducción simple al inglés del fragmento de gramática en la respuesta de @Als :-)

Un número entero con el prefijo 0x es no con el prefijo 0 . 0x es un prefijo explícitamente diferente. Aparentemente hay personas que no pueden hacer esta distinción.

Según ese mismo estándar, si continuamos:

 integer-literal:
     decimal-literal integer-suffixopt
     octal-literal integer-suffixopt
     hexadecimal-literal integer-suffixopt
 decimal-literal:
     nonzero-digit                       <<<---- That's the case of no prefix.
     decimal-literal digit-separatoropt digit
 octal-literal:
     0                                    <<<---- '0' prefix defined here.
     octal-literal digit-separatoropt octal-digit <<<---- No 'x' or 'X' is
                                                          allowed here.
 hexadecimal-literal:
     0x hexadecimal-digit                 <<<---- '0x' prefix defined here
     0X hexadecimal-digit                 <<<---- And here.
     hexadecimal-literal digit-separatoropt hexadecimal-digit