为什么当函数参数未定义为常量引用时存在无限递归?
Why there is an infinite recursion when function parameter is not defined as const reference?
我很难理解可能导致无限递归的原因。有两点在我的问题中起作用
- 取决于全局函数的定义位置
- 我们是否将参数标记为第二个函数(全局或类成员(的 const-ref
这是代码
#include <iostream>
#include <optional>
#include <vector>
using dataType = int;
using dataTypeReturn = float;
//#define ENABLE_AFTER // For global fncs causes inf recursion
#define CONST_REF_FUNCTION // Causes expected behavior when !ENABLED_AFTER
#define CONST_REF_CLASS // Causes expected behavior
#ifndef ENABLE_AFTER
#ifdef CONST_REF_FUNCTION
// Causes expected behavior
std::vector<dataTypeReturn> foo(const dataType& bar){
#else
std::vector<dataTypeReturn> foo(dataType& bar){
#endif
std::cout << "foo(const dataType& bar)" << std::endl;
return std::vector<dataTypeReturn>(10, dataTypeReturn{});
}
#endif
std::vector<dataTypeReturn> foo(const std::optional<dataType>& bar){
std::cout << "foo(const std::optional<dataType>& bar)" << std::endl;
if(bar == std::nullopt)
return {};
return foo(*bar);
}
#ifdef ENABLE_AFTER
#ifdef CONST_REF_FUNCTION
// Causes infinite recursion
std::vector<dataTypeReturn> foo(const dataType& bar){
#else
std::vector<dataTypeReturn> foo(dataType& bar){
#endif
std::vector<dataTypeReturn> foo(const dataType& bar){
std::cout << "foo(const dataType& bar)" << std::endl;
return std::vector<dataTypeReturn>(10, dataTypeReturn{});
}
#endif
class Wrapper{
public:
std::vector<dataTypeReturn> foo(const std::optional<dataType>& bar){
std::cout << "foo(const std::optional<dataType>& bar)" << std::endl;
if(bar == std::nullopt)
return {};
return foo(*bar);
}
private:
#ifdef CONST_REF_CLASS
// Causes expected behavior
std::vector<dataTypeReturn> foo(const dataType& bar){
#else
// Causes infinite recursion
std::vector<dataTypeReturn> foo(dataType& bar){
#endif
std::cout << "foo(const dataType& bar)" << std::endl;
return std::vector<dataTypeReturn>(10, dataTypeReturn{});
}
};
int main(int argc, char** argv){
std::optional<dataType> myoptional(dataType{});
foo(myoptional);
Wrapper mywrapper;
mywrapper.foo(myoptional);
return 0;
}
- 对于全局函数,为什么取决于我定义函数的位置是否发生递归?决定调用什么函数的编译过程是什么?
- 在这两种情况下,将参数标记为接收可选基础类型的函数的 const 引用不会在递归中产生,为什么?我正在查看
std::optional
的构造函数实现,我认为唯一可以匹配的是template < class U = value_type > constexpr optional( U&& value );
但我不明白*bar
如何最终成为 rvalue-ref。
您正在取消引用const optional<datatype>
,您使用的是const value_type & optional::operator*() const
,而不是value_type & optional::operator*()
。
自由函数定义仅查看在其前面声明的名称。这是在标头中声明函数的原因之一。对于成员函数,成员的定义将看到成员的所有声明。
foo(dataType& bar)
不是可行的过载。如果你在定义foo(const optional<dataType>& bar)
之前没有声明foo(const dataType& bar)
,唯一可行的重载是foo(const optional<dataType>& bar)
,它构造一个临时的可选。它推导出U
为const dataType &
,const dataType & &&
被折叠为const dataType &
相关文章:
- C++模板来检查友元函数的存在
- 既然存在危险,为什么项目要使用-I include开关
- 我们可以访问一个不存在的联盟的成员吗
- C++:对不存在的命名空间使用命名空间指令
- C++quit()函数中可能存在作用域问题
- C++擦除(如果存在)
- g++ 说函数不存在,即使包含正确的标头
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 有了gcc,是否可以链接库,但前提是它存在
- visual是否可以在c++中创建一个接收无限数量相同类型(或至少相当数量)参数的函数
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- C++Builder中的OnClick事件签名存在问题
- 如何正确地将分支添加到已存在的树中
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 如何检查QList中是否存在值
- 循环无限运行C++解决骑士之旅问题
- 过载'operator new'如何导致无限循环?
- 根据某个函数是否存在启用模板
- 为什么当函数参数未定义为常量引用时存在无限递归?