从拥抱类型获取模板参数的值

时间:2014-03-16 16:41:57

标签: c++ templates template-specialization

说,我有一个带有整数参数的模板类:

template <int N>
class A
{
public:
    static int get_N()
    {
        return N;
    }
};

template<typename T>
class B
{
public:
    B()
    {
        cout << "N = " << T::get_N() << endl; // Accessing N via the auxiliary method
    }
};

要引用B类中的N模板参数,我必须在A中创建一个辅助方法。我想做这样的事情:

template <int N>
class A
{
};

template<typename T>
class B
{
public:
    B()
    {
        cout << "N = " << T::N << endl; // Accessing N directly
    }
};

问题是我将有很多A模板专业化,而且我并不想将这种辅助方法复制到所有专业课程中,我不想介绍为此继承。 是否有可能实现我想要的目标?

2 个答案:

答案 0 :(得分:5)

您可以从专业化中推断出值:

#include <iostream>

template <typename T> struct get_N;
template <template <int N> class T, int N>
struct get_N<T<N>> {
    static constexpr int value = N;
};

template <int N> struct A {};

template <typename T>
struct B {
    void f() { std::cout << get_N<T>::value << '\n'; }
};

int main() {
    B<A<10>>().f();
}

答案 1 :(得分:1)

您可以像这样提取N

template<typename A>
struct get_N;

template<int N>
struct get_N<A<N> > : std::integral_constant<int,N> { };

这样您就不需要在每个A专业化中定义任何内容,但您可以这样说。

using X = A<3>;
cout << "N = " << get_N<X>() << endl;  // prints: N = 3

但是,我可能仍然希望让A派生一个轻量级模板类,它只定义一个static constrexpr变量,就像在juanchopanza的答案中一样。然后每个A专业化看起来像

template<>
struct A<3> : A_base<3> { ... };

这不是太糟糕。事实上,再次查看这两个选项,我发现A_base只不过是

template<int N>
using A_base = std::integral_constant<int,N>;

所以可以给它一个更通用的短名称。我通常将其称为num