无法推断模板参数

时间:2015-07-24 09:51:53

标签: c++ templates c++11

我有以下类结构,它试图生成编译时生成的树层次结构

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移动到类级别模板中来修复错误,但这会产生一些相当可怕的后果,因为参数列表将在树层次结构的每个级别上增长。我确定编译器应该能够推断出类型,这取决于提供给构造函数的初始化列表的长度。有什么想法吗?

2 个答案:

答案 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仅适用于静态成员,但您似乎满足此要求。