I'm having some trouble understanding how the C++14 extension of the auto
type-specifier described in N3638 can possibly be implemented, and what, exactly, is allowed.
Specifically, one of the changes to the standard says,
If the declared return type of the function contains a placeholder type, the return type of the function is deduced from return statements in the body of the function, if any.
It is easy enough to see how this works when body of the function is in the same file as the declaration; but consider the case where a header file declares a method using the auto
placeholder but does not define it. How can translation units that include this header file but do not include the file that defines the method be successfully compiled?
For instance, given the 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
on its own? If not, why not? If so, how is get_x
instantiated, since there's no way for the compiler to know whether or not the return type of gen_data
even has a member named x
, let alone what its offset is?
This seems like it would be a problem even without worrying about template instantiation, though; for instance, what would happen if you tried accessing f.gen_data().x
directly, or passing it to a function?