Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

c++ - Using functions that return placeholder types defined in another translation unit

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The applicable rule is found in §7.1.6.4 [dcl.spec.auto]/p11:

If the type of an entity with an undeduced placeholder type is needed to determine the type of an expression, the program is ill-formed.

There's an example:

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

You need the type of gen_data to determine the type of the expression x.gen_data(); hence the program is ill-formed. To use such a function, the definition must be visible to the compiler.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...