使用返回在另一个翻译单元中定义的占位符类型的函数 [英] 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,
如果函数的声明的返回类型包含占位符类型,则从函数主体中的return语句(如果有)中推断出函数的返回类型.
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.
很容易看出,当函数体与声明位于同一文件中时,它是如何工作的;但是考虑头文件使用auto
占位符声明方法但不定义的情况.
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?
例如,给定文件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_data
的返回类型是否甚至有一个名为x
的成员,更不用说其偏移量了吗?
...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?
即使不担心模板实例化,这似乎也是一个问题.例如,如果您尝试直接访问f.gen_data().x
或将其传递给函数会发生什么情况?
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?
推荐答案
适用的规则在第7.1.6.4节[dcl.spec.auto]/p11中找到:
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.
有一个例子:
auto f();
void g() { &f; } // error, f’s return type is unknown
您需要gen_data
的类型来确定表达式x.gen_data()
的类型;因此该程序格式不正确.要使用这种功能,定义必须对编译器可见.
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.
这篇关于使用返回在另一个翻译单元中定义的占位符类型的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!