当我尝试编译并运行此代码时(只有前三行真正重要):

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;
       ^

我如何在不改变所有顺序的情况下编译它?在我的实际代码中,声明是在一起的,而定义则分布在多个文件中。是否可以在不分离声明的情况下解决?

为什么在这个阶段类型不完整很重要?

最佳答案



您不必更改所有内容的顺序,但确实需要更改某些内容的顺序。特别是,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){}

当然,您不应该仅仅为了解决这个问题而制作模板,但这是在您编写模板时需要注意的一个方便的细节。

关于c++ - 使用返回不完整类型的函数作为默认参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51139207/

10-13 04:56