3

我很难理解如何实现N3638auto中描述的类型说明符的 C++14 扩展,以及究竟允许什么。

具体来说,该标准的一项更改说,

如果函数声明的返回类型包含占位符类型,则函数的返回类型是从函数体中的返回语句推导出来的,如果有的话。

当函数体与声明在同一个文件中时,很容易看出这是如何工作的;但考虑头文件使用auto占位符声明方法但未定义它的情况。包含此头文件但不包含定义方法的文件的翻译单元如何编译成功?

例如,给定文件foo.hpp

class foo
{
  public:
    auto gen_data();
};

...和文件foo.cpp

struct data_struct
{
  int a;
  int b;
  int c;
  double x;
  char data[37];
};

auto foo::gen_data()
{
  data_struct d;
  // initialize members in d...
  return d;
}

...和文件main.cpp

#include "foo.hpp"

template<typename T>
double get_x(T f)
{
  return f.gen_data().x;
}

int make_and_get_x()
{
  foo f;
  return get_x<foo>(f);
}

main.cpp...自行编译是否合法?如果不是,为什么不呢?如果是这样,如何get_x实例化,因为编译器无法知道gen_dataeven 的返回类型是否有一个名为 的成员x,更不用说它的偏移量是多少了?

不过,即使不担心模板实例化,这似乎也是个问题;例如,如果您尝试f.gen_data().x直接访问或将其传递给函数会发生什么?

4

1 回答 1

2

适用规则见 §7.1.6.4 [dcl.spec.auto]/p11:

如果需要具有未推导的占位符类型的实体的类型来确定表达式的类型,则程序是非良构的。

有一个例子:

auto f();
void g() { &f; }  // error, f’s return type is unknown

您需要的类型gen_data来确定表达式的类型x.gen_data();因此该程序格式错误。要使用这样的函数,定义必须对编译器可见。

于 2015-01-02T18:50:48.080 回答