如何使用decltype作为模板化类的返回类型的模板参数?

时间:2013-11-19 00:26:10

标签: c++ templates c++11 decltype

请参阅以下代码

    template <typename T> 
    struct Node
    {
      T data;
      Node<T>* left;
      Node<T>* right;

      Node (T d, Node<T>* l = nullptr, Node<T>* r = nullptr) : data(d), left(l), right(r) {}
    };

    template <typename ItType>
    auto buildBinaryTree (ItType start, ItType end) -> Node<decltype(*start)>* // doesn't like this line
    {
      // implementation removed for simplicity of post as the signature is the issue
    }

    template <typename T> 
    Node<T>* buildBinaryTree (std::vector<T>& v)
    {
      if  ( v.empty() )
       return nullptr; 

      std::sort(v.begin(), v.end());
      return buildBinaryTree (v.begin(), v.end()); 
    }

int main()
{
  std::vector<int> v { 1,2,3,4,5,6,7,8,9,10 };
  Node<int>* root = buildBinaryTree ( v );

基本上,当我收到编译错误时,实现以下签​​名的最佳方法是什么

main.cpp:81:10: error: cannot initialize return object of type 'Node<int> *'
      with an rvalue of type 'Node<decltype(* start)> *'
  return buildBinaryTree (v.begin(), v.end());

2 个答案:

答案 0 :(得分:4)

试试这个:

Node<typename std::decay<decltype(*start)>::type> *

您需要#include <type_traits>

更清洁的解决方案可能是使用std::iterator_traits<ItType>::value_type

答案 1 :(得分:3)

如果您使用标准库的容器,也许最好的解决方案如下:

template <typename ItType>
auto buildBinaryTree (ItType start, ItType end) -> Node<typename ItType::value_type>* 

更新:我们需要value_type的额外级别的间接服务,如下所示:std::iterator_traits<ItType>::value_type(友善pointed out by Praetorian)。


另一种解决方案是改变

auto buildBinaryTree (ItType start, ItType end) -> Node<decltype(*start)>* 

到此(您可能需要#include <type_traits>):

auto buildBinaryTree (ItType start, ItType end) -> Node<typename std::remove_reference<decltype(*start)>::type>* 

gcc错误消息很明确:

  

错误:无法将Node<int&>*转换为Node<int>*作为回报

显然,你正在使用clang,遗憾的是,它没有给出如此清晰的错误信息...... :(