C++ 如何使用decltype作为模板化类的返回类型的模板参数?
请参阅下面的代码C++ 如何使用decltype作为模板化类的返回类型的模板参数?,c++,templates,c++11,decltype,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 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 );
模板
结构体类型
{
T数据;
节点*左;
节点*右;
节点(td,Node*l=nullptr,Node*r=nullptr):数据(d),左(l),右(r){
};
模板
自动构建二进制树(ItType start,ItType end)->Node*//不喜欢这一行
{
//为简化post,删除了实现,因为签名是问题所在
}
模板
节点*buildBinaryTree(std::vector&v)
{
if(v.empty())
返回空ptr;
排序(v.begin(),v.end());
返回buildBinaryTree(v.begin(),v.end());
}
int main()
{
向量v{1,2,3,4,5,6,7,8,9,10};
Node*root=buildBinaryTree(v);
基本上,当我遇到编译错误时,实现以下签名的最佳方法是什么
main.cpp:81:10:错误:无法初始化“Node*”类型的返回对象
具有“Node*”类型的右值
返回buildBinaryTree(v.begin(),v.end());
试试这个:
Node<typename std::decay<decltype(*start)>::type> *
节点*
您需要#包括
一个更干净的解决方案可能是使用std::iterator\u traits::value\u type
。如果使用标准库的容器,最好的解决方案可能是:
template <typename ItType>
auto buildBinaryTree (ItType start, ItType end) -> Node<typename ItType::value_type>*
为此(您可能需要#包括):
autobuildbinarytree(ItType开始,ItType结束)->Node*
gcc错误消息很清楚:
错误:无法将节点*
转换为节点*
显然,您使用的是clang,不幸的是,它没有给出如此明确的错误消息…:(如果迭代器类型恰好是原始指针,那么typename ItType::value\u type
解决方案将失败,即使是标准的库容器也允许使用原始指针。您需要额外的间接寻址级别,方法是将其包装在std::iterator\u traits::value\u type
中,以使代码可移植。@Praetorian非常感谢您将其指向t out;修复了答案中的问题。是的@Ali我在mac上这么做:),我在家使用linux上的gcc:)。这个编译器错误肯定会解决这个问题。再次感谢您的回答。@bjackfly我很高兴它能帮上忙!详细说明一下,问题是*start
是一个左值,而不是标识符,因此它的decltype
生成一个引用类型。decay
删除了引用。感谢@Potatoswatter这有助于澄清这更进一步。谢谢@Kerrek投票回答。
template <typename ItType>
auto buildBinaryTree (ItType start, ItType end) -> Node<typename ItType::value_type>*
auto buildBinaryTree (ItType start, ItType end) -> Node<decltype(*start)>*
auto buildBinaryTree (ItType start, ItType end) -> Node<typename std::remove_reference<decltype(*start)>::type>*