gpt4 book ai didi

c++ - 接收右值并调用左值版本的函数的无限递归

转载 作者:行者123 更新时间:2023-11-27 22:58:13 24 4
gpt4 key购买 nike

基本上我有以下几种情况

   template <class GT>
GT create_graph(size_t n)
{
GT ret;
// some stuf on ret

return ret;
}

template <class GT>
void test(const GT & g)
{
// processing on g
}

template <class GT>
void test(GT && g)
{
test(g); // call to const GT& (lvalue version)
}

int main()
{
test(create_graph<Graph>(100));
test(create_graph<SGraph>(100));
test(create_graph<AGraph>(100));
}

所有三种类型(Graph、SGraph、AGraph)都有复制和移动构造函数以及赋值运算符。

右值版本是暂时的。之后我会写一个专门的版本。但与此同时,我调用了左值版本。

根据我的理解,第一行(以及后续行)创建了一个右值对象(通过调用 create_graph())。此右值传递给 test() 的右值版本,它调用 test() 的左值版本(如果这不完全正确,请纠正我)。

现在,由于我无法理解的原因,test() 的右值版本属于无限递归。显然,它将 g 作为右值处理。如我所见,参数 g(不执行前移)是一个左值。

我用两个不同的编译器进行了测试,我的代码都属于无限递归。因此,我得出结论,我做错了什么,要么是因为我缺乏理解,要么是因为 GT 的实例发生了某些事情,使编译器将 g 解释为右值。

所以,如果有人能提出一个解释来澄清我正在发生的事情,那么我将非常感激

最佳答案

您的临时对象不是const,因此您可以递归调用通用引用函数重载。改用这个:

template <class GT>
void test(GT && g)
{
test(static_cast<std::remove_reference_t<GT> const&>(g));
}

Scott Meyers 建议的另一种选择是使用调度:

template <class GT>
void test(GT &&g, std::true_type)
{
//implementation for l-value references
}

template <class GT>
void test(GT &&g, std::false_type)
{
//implementation for r-value references
}

然后从原来的函数中调用那些

template <class GT>
void test(GT &&g)
{
test(std::forward<GT>(g), std::is_lvalue_reference<GT>());
}

关于c++ - 接收右值并调用左值版本的函数的无限递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30471590/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com