C ++ 11模板中的一个参数可以依赖于另一个吗?

时间:2015-07-02 22:06:16

标签: c++ templates c++11 typename

我的类SimRank有两个浮点常量参数,C和D.我希望它们是静态constexprs,而不是const实例成员。但我也希望让用户选择使用哪个浮点数,float表示大小,或double表示精确度。

显而易见的方法是:

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;
}

但是当我尝试这个时,gcc会打印许多错误消息,所以显然语法不存在。我也做不了这样的事情:

template<typename FP> template<int _K, FP _C, FP _D> class SimRank {...};

是否有任何语法可以让我在编译时指定K,C,D以及C和D的类型?现在我已经为const成员定居了:

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;
}

(实际上,即使我必须保留const成员解决方案,我想要一种方法来定义SimRankF和SimRankD而不重复每个构造函数。当我尝试实例化时,将它留出来使得gcc print error: no matching function for call to 'SimRankF::SimRankF(int, float, float)'一个SimRankF。)

2 个答案:

答案 0 :(得分:6)

有两个问题,

首先,模板非类型参数cannot be of type float or double

其次,部分特化声明的语法(及其在main中的使用)是错误的。

它与C ++ 11,BTW无关。

阅读有关C ++模板的介绍性文章是最适合您的方式。

答案 1 :(得分:3)

你不能使用:

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;
};

FP的预期类型为floatdouble,因为非类型模板参数不能是floatdouble

您可以使用您提出的解决方案:

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) {}
};

不清楚K将如何使用,但您也可以使用:

template<typename FP, int K>
class SimRank {
private:
    const FP C;
    const FP D;
public:
    SimRank(FP C, FP D) : C(C), D(D) {}
};

并创建类的实例:

SimRank<double, 5> sd(0.8, 0.0);
SimRank<float, 10> sf(0.8f, 0.0f);