#include <iostream>
using namespace std;
enum Flavor { Cherry, Plum, Raspberry };
template <Flavor> using Number = double;
void printCherryNumber(Number<Cherry> num) { cout << num << endl; }
template <typename T> void printCherryNumber(T num) = delete;
// Doesn't work. "Cannot infer type argument F."
template <Flavor F>
void printPlumNumber(Number<F> num) {
static_assert(F == Plum, "Wrong number flavor!");
cout << num << endl;
}
// Doesn't work. Compiler rightly treats the call as ambiguous.
template <Flavor F> void printRaspberryNumber(Number<F> num) = delete;
template <> void printRaspberryNumber<Raspberry>(Number<Raspberry> num) {
cout << num << endl;
}
int main() {
Number<Cherry> a(5);
Number<Plum> b(6);
Number<Raspberry> c(3.1415);
printCherryNumber(a);
printCherryNumber(b); // O, if only this could be a compiler error.
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKZW51bSBGbGF2b3IgeyBDaGVycnksIFBsdW0sIFJhc3BiZXJyeSB9OwoKdGVtcGxhdGUgPEZsYXZvcj4gdXNpbmcgTnVtYmVyID0gZG91YmxlOwoKdm9pZCBwcmludENoZXJyeU51bWJlcihOdW1iZXI8Q2hlcnJ5PiBudW0pIHsgY291dCA8PCBudW0gPDwgZW5kbDsgfQoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IHZvaWQgcHJpbnRDaGVycnlOdW1iZXIoVCBudW0pID0gZGVsZXRlOwoKLy8gRG9lc24ndCB3b3JrLiAiQ2Fubm90IGluZmVyIHR5cGUgYXJndW1lbnQgRi4iCnRlbXBsYXRlIDxGbGF2b3IgRj4Kdm9pZCBwcmludFBsdW1OdW1iZXIoTnVtYmVyPEY+IG51bSkgewoJc3RhdGljX2Fzc2VydChGID09IFBsdW0sICJXcm9uZyBudW1iZXIgZmxhdm9yISIpOwoJY291dCA8PCBudW0gPDwgZW5kbDsKfQoKLy8gRG9lc24ndCB3b3JrLiBDb21waWxlciByaWdodGx5IHRyZWF0cyB0aGUgY2FsbCBhcyBhbWJpZ3VvdXMuCnRlbXBsYXRlIDxGbGF2b3IgRj4gdm9pZCBwcmludFJhc3BiZXJyeU51bWJlcihOdW1iZXI8Rj4gbnVtKSA9IGRlbGV0ZTsKCnRlbXBsYXRlIDw+IHZvaWQgcHJpbnRSYXNwYmVycnlOdW1iZXI8UmFzcGJlcnJ5PihOdW1iZXI8UmFzcGJlcnJ5PiBudW0pIHsKCWNvdXQgPDwgbnVtIDw8IGVuZGw7Cn0KCmludCBtYWluKCkgewoJTnVtYmVyPENoZXJyeT4gYSg1KTsKCU51bWJlcjxQbHVtPiBiKDYpOwoJTnVtYmVyPFJhc3BiZXJyeT4gYygzLjE0MTUpOwoJCglwcmludENoZXJyeU51bWJlcihhKTsKCXByaW50Q2hlcnJ5TnVtYmVyKGIpOyAgLy8gTywgaWYgb25seSB0aGlzIGNvdWxkIGJlIGEgY29tcGlsZXIgZXJyb3IuCgkKCXJldHVybiAwOwp9