Using functions that return placeholder types defined in a different translation unit

I am having trouble understanding how the C ++ 14 extension to the type specifier auto

described in N3638 might possibly be implemented, and what exactly is allowed.

In particular, one of the changes to the standard says,

If the declared return type of a function contains a placeholder type, the return type of the function is inferred from the return statements in the body of the function, if any.

It's easy to see how this works when the body of the function is in the same file as the declaration; but consider the case where the header file declares a method using auto

placeholder but does not define it. How can one compile translation units that include this header file but not the file that defines the method?

For example, for a file foo.hpp

:

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

      

... and file 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;
}

      

... and file 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);
}

      

... is it legal to compile main.cpp

yourself? If not, why not? If so, how is it created get_x

, since the compiler doesn't know if the return type gen_data

even has a named member x

, let alone what its offset?

It looks like this is a problem without even bothering to create a template; for example, what happens if you try to access f.gen_data().x

or pass it to a function directly ?

+3


source to share


1 answer


The corresponding rule is contained in clause 7.1.6.4 [dcl.spec.auto] / p11:

If you need an object type with an unapproved placeholder type to determine the type of the expression, your program is ill-formed.

Here's an example:



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

      

You need a type gen_data

to determine the type of the expression x.gen_data()

; hence the program is poorly formed. To use such a function, the definition must be visible to the compiler.

+2


source







All Articles