Non so se essere contento o meno di tutta questa javascriptazione del C++! :-P
Sicuramente le proverò anch'io, ma queste "template union Either" non mi sembrano niente di nuovo alla fine... la variabile che segnala il tipo di struttura è sempre esistita, sebbene mi ricordavo che io (ai tempi del C) usavo una forma ancora più azzardata, del tipo:
struct stProva1 {
int tipo; // 1
char *dati1;
char *dati2;
};
struct stProva2 {
int tipo; // 2
char *dati3;
char *dati4;
char *dati5;
};
union uniProva1 {
struct stProva1 p1;
struct stProva2 p2;
};
... dove "tipo" indicava appunto che tipo di struttura era. Lo 0 non era mai assegnato a nulla, così da poter identificare le strutture "callocate" ma non inizializzate.
Mentre in C le union le evitavo come il morbillo, in C++ non mi è mai balenata l'idea di usarle! Anche perchè si potrebbe restituire una classe (con smart pointer) o usare una più banale stringa membro pubblica std::string strErrno
(oppure una std::list<std::string> lstErrno
globale per essere thread safe e old school allo stesso tempo), poi restituire puntatori nulli, eccezioni o strutture vuote ai chiamanti... e rassegnarsi a gestire gli errori! Purtroppo gli errori sono cruciali: se li prevedi ma poi li ignori e non li gestisci, avrai senz'altro dei problemi prima o poi.
Sarà anche brutto disaccoppiare l'errore dalla funzione che lo ha generato, ma se l'Either ha lo scopo di concatenare le funzioni alla javascript per emularne il suo comportamento allora preferisco una soluzione più old school ma meno obbrobbriosa (se esiste la parola)... perchè a questo punto lascio perdere il C++ e vado direttamente di node.js! 😛
UPDATE: Altra cosa che davo per scontata ma che non ho scritto... 😎
Stare a gestire un tipo oppure un altro in maniera concatenata (come si vede su hackernoon) è nell'atto pratico dannoso e inutile: "dannoso" perchè non verranno gestiti bene gli eventuali errori che capiteranno in mezzo (in un contesto più complesso dell'esempio), "inutile" perchè le lambda farebbero di fatto la stessa cosa delle if (come già accennato da @theGiallo)... E se devo usare un selettore per richiedere una versione stringa o una versione numerica, a questo punto faccio 2 funzioni diverse!
Non ho visto nei dettagli come funziona quella join, ma a sensazione immagino che internamente ci sia una lista di tipi variant che poi verranno tutti concatenati e convertiti in un tipo unico (stringa o intero). E in tal caso non ci sarebbe niente di nuovo rispetto a sommare i numeri insieme o a concatenare le stringhe dentro una stringstream. Quindi a sensazione mi sembra migliore fare un std::cout << mioIntero << ' ' << miaStringa << std::endl;
e supportare i template standard, piuttosto che implementare le Either.