【问题标题】:Incomplete types as function parameters and return values作为函数参数和返回值的不完整类型
【发布时间】:2018-05-28 18:12:49
【问题描述】:

以下代码compiles successfully both with clang++ 5.0.0 and g++ 7.2(带有-std=c++17 -Wall -Wextra -Werror -pedantic-errors -O0 编译标志):

struct Foo;

struct Bar
{
    Foo get() const;

    void set(Foo);
};

struct Foo
{
};

Foo Bar::get() const
{
    return {};
}

void Bar::set(Foo)
{
}


int main()
{
    Bar bar{};

    (void)bar.get();
    bar.set(Foo{});
}

使用不完整类型作为函数参数和返回值是否有效? C++ 上面写了什么?

【问题讨论】:

  • 这基本上是你在任何标题中所做的......
  • @Jaa-c 听起来可能很傻,但我之前从未在头文件中使用不完整类型作为函数返回类型或参数类型。
  • 这个想法是你不会让每个可能间接包含你的标题的人必须解析它使用的每种类型的完整定义,因为他们可能不要使用需要所述定义的函数。如果他们,那么他们可以自己包含完整的定义。不过,我认为对你的用户的期望是否好,争论会永远激烈地进行。对于内部使用的标头,我会说这是不费吹灰之力。

标签: c++ language-lawyer c++17 return-type incomplete-type


【解决方案1】:

据我所知,你可以通过以下方式使用不完整类型:

  1. 作为指针;
  2. 作为参考;

因为函数的声明没有创建任何对象,所以是合法的。

【讨论】:

    【解决方案2】:

    使用不完整类型作为函数参数和返回值是否有效? C++ 上面写了什么?

    在函数声明中,是的,它是有效的。

    [basic.def.odr] 列出类型必须完整的情况。该列表中没有提及函数声明。请注意,对于 T 的参数和返回类型,函数定义确实需要 T 的定义。

    【讨论】:

    • 为什么不在标头中定义返回类型T 会有问题?调用者只需要为它添加一个#include,作为一个非常小的不便的回报,你减少了其他人的编译时依赖,因为不是每个需要fun.h的人都可以真正调用这个函数,尤其是当我们在说话的时候关于成员函数。
    【解决方案3】:

    在函数定义中,不能使用不完整类型:[dcl.fct]/12:

    函数定义的参数类型或返回类型在函数定义的上下文中不得是不完整的(可能是cv-限定的)类类型,除非该函数被删除。

    但是函数声明没有这样的限制。当你定义Bar::getBar::set时,Foo是一个完整的类型,所以程序没问题。

    【讨论】:

      猜你喜欢
      • 2018-12-10
      • 2021-03-23
      • 1970-01-01
      • 2021-04-02
      • 2023-02-01
      • 1970-01-01
      • 2010-10-14
      • 2022-01-16
      • 2021-04-11
      相关资源
      最近更新 更多