使用返回不完整类型的函数作为默认参数

时间:2018-07-02 15:13:36

标签: c++ default-parameters incomplete-type

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

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

如何在不更改所有内容顺序的情况下进行编译?在我的实际代码中,声明是在一起的,而定义则分布在多个文件中。是否可以在不分隔声明的情况下进行求解?

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

2 个答案:

答案 0 :(得分:3)

在发生错误时,已预先声明了对象,但尚未到达其定义,因此对象是不完整的类型。您只能将指针指向不完整的类型。

您需要具有这样的完整定义

git config --global user.useConfigOnly true

或者如果您不想重新排序,则必须通过指针传递所有内容

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(){}

但是第一个解决方案确实更好

答案 1 :(得分:3)

  

如何在不更改所有内容顺序的情况下进行编译?

您不必更改一切的顺序,但是您确实需要更改事物的顺序。特别是,必须在调用=switch(Fields!Name.value ="Alex" and Fields!Total.value >=11, "LightGreen", Fields!Name.value = "Alex" and Fields!Total.value >=8 and Fields!Total.value <=10, "Orange", Fields!Name.value = "Alex" and Fields!Total.value <=7,"Red") or switch(Fields!Name.value ="Harry" and Fields!Total.value >=11, "LightGreen", Fields!Name.value = "Harry" and Fields!Total.value >=8 and Fields!Total.value <=10, "Orange", Fields!Name.value = "Harry" and Fields!Total.value <=7,"Red") 之前(在默认参数表达式中)定义object

  

是否可以在不分隔声明的情况下进行求解?

目前尚不清楚这是什么意思,但是如果在顶部定义getObject,则声明可以保持与示例中相同。

另一种选择是在object定义之后使用默认参数重新声明该函数:

object

这当然意味着在第一个声明之后但在重新声明之前的代码不会从默认参数中受益。

最后,有些技巧。模板实例化之前,模板中的表达式不需要完整,因此如果class object; object getObject(); void doSomething(object o); class object{ public: int num = 0; }; void doSomething(object o = getObject()); 是函数模板,则您的示例可以正常工作:

doSomething

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