使用返回不完整类型的函数作为默认参数
Posted
技术标签:
【中文标题】使用返回不完整类型的函数作为默认参数【英文标题】:Use function returning incomplete type as default argument 【发布时间】:2018-12-10 20:39:24 【问题描述】:当我尝试编译和运行这段代码时(只有前三行很重要):
class object;
object getObject();
void doSomething(object o = getObject());
class object
public:
int num = 0;
;
object getObject()
return ;
void doSomething(object o)
o.num = 5;
int main()
我收到此错误:
main.cpp:3:39: error: invalid use of incomplete type 'class object'
void doSomething(object o = getObject());
^
main.cpp:1:7: note: forward declaration of 'class object'
class object;
^
如何在不改变所有顺序的情况下编译它?在我的实际代码中,声明是在一起的,而定义分布在多个文件中。是否可以在不分离声明的情况下解决?
在这个阶段如果类型不完整有什么关系?
【问题讨论】:
@demogorgon.net 读取语言标签。 C++ 允许这样的语法。new object()
将是 object *
,而不是 object
@Ptaq666 你可以声明一个带有不完整类型的对象参数的函数。您只是不能调用返回不完整类型的对象(或具有不完整类型的参数)的函数。这里的问题是默认参数表达式是对此类函数的调用。
@user2079303 为什么在这个阶段调用函数?我的困惑是为什么 C++ 在使用 doSomething() 之前需要有一个完整的类型。内存分配了吗?
@user2079303,没错,我删除了我的评论。
@user4913118 getObject()
是一个函数调用表达式。这里的所有都是它的。语言规则根本不允许它在 getObject
的返回类型完成之前出现。
【参考方案1】:
如何在不改变所有顺序的情况下编译它?
您不必更改 everything 的顺序,但您需要更改 something 的顺序。特别是,object
必须在调用 getObject
之前定义(在默认参数表达式中)。
是否可以在不分离声明的情况下解决问题?
有点不清楚这意味着什么,但如果您在顶部定义 object
,则声明可以与您的示例中的完全相同。
另一种选择是在object
定义之后用默认参数重新声明函数:
class object;
object getObject();
void doSomething(object o);
class object
public:
int num = 0;
;
void doSomething(object o = getObject());
这当然意味着在第一次声明之后,但在重新声明之前的代码不会受益于默认参数。
最后,有点技巧。在模板实例化之前,模板中的表达式不需要完整,因此如果 doSomething
是函数模板,您的示例将可以正常工作:
template<class T=void>
void doSomething(object o = getObject());
class object;
object getObject()
return ;
template<class T>
void doSomething(object o)
当然,您不应该仅仅为了解决这个问题而制作模板,但这是您在编写模板时需要注意的一个方便的细节。
【讨论】:
【参考方案2】:在发生错误时,对象已被前向声明,但尚未达到其定义的 bean,因此对象是不完整的类型。你只能有不完整类型的指针。
你需要有这样的完整定义
class object
public:
int num = 0;
;
object getObject();
void doSomething(object o = getObject());
object getObject()
return ;
void doSomething(object o)
o.num = 5;
int main()
或者如果您不想重新排序,则必须通过指针传递所有内容
class object;
object* getObject();
void doSomething(object* o = getObject());
class object
public:
int num = 0;
;
object* getObject()
return new object();
void doSomething(object* o)
o->num = 5;
delete o;
int main()
但第一个解决方案确实更好
【讨论】:
以上是关于使用返回不完整类型的函数作为默认参数的主要内容,如果未能解决你的问题,请参考以下文章