Sono incuriosito. Quindi, è tempo di indossare gli occhiali di indagine e dato che non ho accesso al compilatore o ai flag di compilazione, devo essere inventivo. Anche perché nulla di questo codice ha senso non è una cattiva idea in ogni ipotesi.
Per prima cosa controlliamo il tipo effettivo di gets. Ho un piccolo trucco per questo:
template <class> struct Name;
int main() {
Name<decltype(gets)> n;
// keep this function call here
cout << FirstFactorial(gets(stdin));
return 0;
}
E questo sembra ... normale:
/tmp/613814454/Main.cpp:16:19: warning: 'gets' is deprecated [-Wdeprecated-declarations]
Name<decltype(gets)> n;
^
/usr/include/stdio.h:638:37: note: 'gets' has been explicitly marked deprecated here
extern char *gets (char *__s) __wur __attribute_deprecated__;
^
/usr/include/x86_64-linux-gnu/sys/cdefs.h:254:51: note: expanded from macro '__attribute_deprecated__'
# define __attribute_deprecated__ __attribute__ ((__deprecated__))
^
/tmp/613814454/Main.cpp:16:26: error: implicit instantiation of undefined template 'Name<char *(char *)>'
Name<decltype(gets)> n;
^
/tmp/613814454/Main.cpp:12:25: note: template is declared here
template <class> struct Name;
^
1 warning and 1 error generated.
getsè contrassegnato come obsoleto e ha la firma char *(char *). Ma allora com'èFirstFactorial(gets(stdin)); compilando?
Proviamo qualcos'altro:
int main() {
Name<decltype(gets(stdin))> n;
// keep this function call here
cout << FirstFactorial(gets(stdin));
return 0;
}
Che ci dà:
/tmp/286775780/Main.cpp:15:21: error: implicit instantiation of undefined template 'Name<int>'
Name<decltype(8)> n;
^
Finalmente stiamo ottenendo qualcosa: decltype(8). Quindi l'intero è gets(stdin)stato sostituito testualmente con l'input (8 ).
E le cose diventano più strane. L'errore del compilatore continua:
/tmp/596773533/Main.cpp:18:26: error: no matching function for call to 'gets'
cout << FirstFactorial(gets(stdin));
^~~~
/usr/include/stdio.h:638:14: note: candidate function not viable: no known conversion from 'struct _IO_FILE *' to 'char *' for 1st argument
extern char *gets (char *__s) __wur __attribute_deprecated__;
Quindi ora otteniamo l'errore previsto per cout << FirstFactorial(gets(stdin));
Ho controllato per una macro e da allora #undef gets sembra non fare nulla sembra che non sia una macro.
Ma
std::integral_constant<int, gets(stdin)> n;
Si compila.
Ma
std::integral_constant<int, gets(stdin)> n; // OK
std::integral_constant<int, gets(stdin)> n2; // ERROR wtf??
Non con l'errore previsto al n2 riga.
E ancora, quasi ogni modifica per mainrendere la lineacout << FirstFactorial(gets(stdin)); sputare l'errore previsto.
Inoltre il stdin realtà sembra essere vuoto.
Quindi posso solo concludere e ipotizzare che abbiano un piccolo programma che analizza la fonte e cerca (male) di sostituire gets(stdin) il valore di input del test case prima di inserirlo nel compilatore. Se qualcuno ha una teoria migliore o effettivamente sa cosa sta facendo, per favore condividi!
Questa è ovviamente una pessima pratica. Durante la ricerca di questo ho scoperto che c'è almeno una domanda qui ( esempio ) su questo e perché le persone non hanno idea che ci sia un sito là fuori che fa questo la loro risposta è "non usare getsuso ... invece" che è davvero un buon consiglio, ma confonde solo di più l'OP poiché qualsiasi tentativo di lettura valida da stdin fallirà su questo sito.
TLDR
gets(stdin)non è C ++ valido. È un espediente che questo particolare sito utilizza (per quali motivi non riesco a capire). Se vuoi continuare a inviare sul sito (non lo sto sostenendo né lo sto sostenendo) devi usare questo costrutto che altrimenti non avrebbe senso, ma tieni presente che è fragile. Quasi tutte le modifiche apportate maingenereranno un errore. Al di fuori di questo sito utilizzare i normali metodi di lettura dell'input.
stdinnella libreria standard è unFILE*, e un puntatore a qualsiasi tipo viene convertito inchar*, che è il tipo dell'argomento digets(). Tuttavia, non dovresti mai, mai, mai scrivere quel tipo di codice al di fuori di un contest offuscato C. Se il compilatore lo accetta, aggiungi altri flag di avviso e se stai cercando di correggere una base di codice che contiene quel costrutto, trasforma gli avvisi in errori.