我有以下类结构,它试图生成编译时生成的树层次结构
struct NodeBase{
virtual constexpr uint32_t size() const = 0;
virtual constexpr bool empty() const = 0;
constexpr NodeBase(){};
};
template <size_t L>
class Node : NodeBase{
private:
const uint32_t * const ptr;
const std::array<const NodeBase &, L> nodes;
public:
constexp Node(std::initializer_list<NodeBase> const ts, uint32_t const * const ptr) :
NodeBase(),
ptr(ptr),
nodes{ts}
{
};
constexpr uint32_t size() const {
return nodes.size();
}
constexpr bool empty() const {
return (ptr==nullptr) ? true : false;
}
}
// helper function should allow for template deduction
template<size_t T>
constexpr Node<T> makeNode(std::initializer_list<NodeBase> const ts, uint32_t const * const ptr){
return Node<T>(ts, ptr);
};
template <size_t L>
class Item : Node{
public:
constexpr Item() :
Node<L>({member}, nullptr)
{
};
private :
// here lies the problem
template <size_t M>
static constexpr Node<M> member = makeNode({},nullptr);
}
然而,这给编译器(gcc 4.9.1)错误: 没有匹配函数调用makeNode(,null_ptr_t),并且说明它不能推断出模板类型。
我可以通过将参数M移动到类级别模板中来修复错误,但这会产生一些相当可怕的后果,因为参数列表将在树层次结构的每个级别上增长。我确定编译器应该能够推断出类型,这取决于提供给构造函数的初始化列表的长度。有什么想法吗?
答案 0 :(得分:3)
如果函数参数中没有使用模板类型,编译器应如何推导模板类型? 可能是你想要的
static constexpr Node<M> member = makeNode<M>({},nullptr);
答案 1 :(得分:1)
根据您的评论,我认为这是您可能想要的。我放弃了使用std::initializer_list
。在C ++ 14中,它应该有一个constexpr
成员来返回元素的数量,但我无法使其工作,无论如何你都标记了你的问题C ++ 11。相反,我使用的是普通的旧C数组,其大小可以通过模板机制推断出来。
template <size_t M>
struct Node {};
template <size_t M>
constexpr Node<M> makeNode(int const (&list)[M])
{
return Node<M>();
}
class Item
{
static constexpr auto member = makeNode({1, 2, 3});
};
请注意,在类范围内使用auto
仅适用于静态成员,但您似乎满足此要求。