My class SimRank has two floating-point constant parameters, C and D. I would like them to be static constexprs, not const instance members. But I also want to let the user choose which kind of floating-point to use, float for size or double for precision.
The obvious way to do it is like this:
template<typename FP, int _K, FP _C, FP _D>
class SimRank {
    static constexpr int K = _K;
    static constexpr FP C = _C;
    static constexpr FP D = _D;
};
template<int _K, float _C, float _D>
class SimRank<float> {};
template<int _K, double _C, double _D>
class SimRank<double> {};
int main() {
    SimRank<5, 0.8, 0> sd; // uses double
    SimRank<10, 0.6f, 0.05f> sf; // uses float
    return 0;
}
But gcc prints many error messages when I try this, so apparently that syntax doesn't exist. I also can't do anything like this:
template<typename FP> template<int _K, FP _C, FP _D> class SimRank {...};
Is there any syntax that lets me specify K, C, D, and the type of C and D at compile time? Right now I've settled for const members:
template<typename FP>
class SimRank {
private:
    const int K;
    const FP C;
    const FP D;
public:
    SimRank(int K, FP C, FP D) : K(K), C(C), D(D) {}
};
class SimRankF : public SimRank<float> {
public:
    SimRankF(int K, float C, float D) : SimRank<float>(K, C, D) {}
};
class SimRankD : public SimRank<double> {
public:
    SimRankD(int K, double C, double D) : SimRank<double>(K, C, D) {}
};
int main() {
    SimRankD sd(5, 0.8, 0.0);
    SimRankF sf(10, 0.6f, 0.05f);
    return 0;
}
(Actually, even if I have to keep the const member solution, I would like a way to define SimRankF and SimRankD without repeating the constructor for each. Leaving it out makes gcc print error: no matching function for call to 'SimRankF::SimRankF(int, float, float)' when I try to instantiate a SimRankF.)
 
     
     
    