我有一个采用整数参数的模板节点类。我还有一个树类,它创建一个节点并将其构造函数参数作为节点模板的参数传递。
Tree.cpp
Tree::Tree(int n) {
this->n = n;
root = new Node<n>(); // compiler error
}
的main.cpp
Tree *tree = new Tree(2);
我的编译器抱怨'n'不是常量表达式。如何成功将n
传递给我的节点类?
答案 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>();