传递变量作为模板参数

时间:2017-02-15 02:31:24

标签: c++ templates

我有一个采用整数参数的模板节点类。我还有一个树类,它创建一个节点并将其构造函数参数作为节点模板的参数传递。

Tree.cpp

Tree::Tree(int n) {
    this->n = n;
    root = new Node<n>(); // compiler error
}

的main.cpp

Tree *tree = new Tree(2);

我的编译器抱怨'n'不是常量表达式。如何成功将n传递给我的节点类?

3 个答案:

答案 0 :(得分:0)

我认为你不能这样做。

n在编译时是已知的,但它不是模板参数。由于您的n构造函数中需要Tree,因此您也可以将Tree类设为模板。

答案 1 :(得分:0)

使构造函数成为模板之一:

struct Base
{

};
template <int N>
struct Node : Base
{

};

class Tree 
{
public:

    template <int N>
    struct size
    {
    };

    template<int N> Tree(size<N>) {
        this->n = N;
        root = new Node<N>();
    }

    int n;
    Base* root;
};

int main() {

    Tree t = Tree(Tree::size<2>());

    return 0;
}

答案 2 :(得分:0)

你做的方式无法奏效,因为n必须在编译时知道 您可以使其成为构造函数模板参数。不幸的是,在这种情况下,它不能明确给出,必须是可推导的。无论如何,这是一个丑陋的语法问题 它遵循一个最小的工作示例:

#include<type_traits>

struct BaseNode {};

template<int n>
struct Node: BaseNode {};

struct Tree {
    template<int n>
    Tree(std::integral_constant<int, n>)
        : n{n}, root{new Node<n>()}
    {}

    int n;
    BaseNode *root;
};

int main() {
    Tree tree{std::integral_constant<int, 2>{}};
}

请注意,您可以使用工厂方法轻松解决难看的语法:

struct Tree {
    template<int n>
    Tree(std::integral_constant<int, n>)
        : n{n}, root{new Node<n>()}
    {}

    template<int n>
    static Tree create() {
        return Tree{std::integral_constant<int, n>{}};
    }

    int n;
    BaseNode *root;
};

// ...

Tree tree = Tree::create<2>();

另一种可能的解决方案是提供Node作为参数并从中推导出n

struct Tree {
    template<int n>
    Tree(Node<n> *node)
        : n{n}, root{node}
    {}

    // ...
};

或者使用两步初始化,并能够明确地将n作为模板参数传递:

struct Tree {
    Tree(): n{0}, root{nullptr} {}

    template<int n>
    void init() {
        this->n = n;
        root = Node<n>;
    }

    int n;
    BaseNode *root;
};

// ...

Tree tree{};
tree.init<2>();