I'd like to add compile-time checking for different meanings of double. In the real world, I'm trying to make sure all calculations are done in consistent units. For the purposes of this question, I've concocted a toy example in which numbers have flavors.
I've been trying to achieve this based on a template parameter. Using the c++0x aliases feature described in another answer, I declared a Number<Flavor> as:
enum Flavor { Cherry, Plum, Raspberry };
template <Flavor> using Number = double;
This gives me the ability to declare local variables or parameters as particular flavors of Number, then use those variables as ordinary doubles in most contexts.
My problem is, I can't find a way to declare a function that will only accept a particular flavor as its argument:
void printCherryNumber(Number<Cherry> 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;
}
My goal is to make printCherryNumber(b) fail to compile because b is a Number<Plum> not Number<Cherry>. Many existing questions tackle variations on this problem with solutions that seem to not work on the type alias construct I've used for Number.
Stuff I've Tried
From this answer, I see the suggestion to add a templated version of the function that explicitly does nothing or breaks, as in
template <typename T> void printCherryNumber(T num) = delete;
This has no effect at all, and why should it? Number<Plum> is really double and Number<Cherry> is also double so the compiler never bothers with the templated version.
Another answer suggests using a single templated function and static asserts, as in:
template <Flavor F> void printPlumNumber(Number<F> num) {
    static_assert(F == Plum, "Wrong number flavor!");
    cout << num << endl;
}
This fails because regardless of the actual value of F, Number<F> is still just double and so I get an error about not being able to infer the value of F.
Elsewhere someone suggests explicit specialization, which also fails for this case:
template <Flavor F> void printRaspberryNumber(Number<F> num) = delete;
template <> void printRaspberryNumber<Raspberry>(Number<Raspberry> num) {
    cout << num << endl;
}
Here, the compiler treats the call as ambiguous, in part again because it can't infer a value for F.
Elephant in the Room
I could, of course, make Number a single-value struct in the form of
template <Flavor> struct Number { double value; };
but I'm trying to avoid this option because I'm not terribly thrilled about the idea of having .value all over everywhere in my code, nor am I especially eager to define operators for Number that just proxy down to double.
 
     
     
    