模板类实例化使用java_如果事后定义了类型,那么实例化一个格式不正确的类模板吗?...

struct A;

template class Foo { };

Foo foo; // note A is incomplete here

struct A {};

Foo 仅取决于 A 的名称而不是其完整类型 .

所以这是良好的形式;但是,这种事情仍然会破坏(变得格式不好),但在您测试的每个编译器中都会编译 .

首先,我们偷了is_complete . 然后我们这样做:

struct A;

template class Foo {

enum{ value = is_complete::value };

};

Foo foo; // note A is incomplete here

struct A {};

尽管如此,我们还可以:

[...]对于在翻译单元内具有实例化点的任何此类专业化,翻译单元的末尾也被视为实例化点 . [...]

因为该子句不适用于模板类 . 这里,模板类的唯一实例化很好 .

现在,如果在另一个文件中,你有:

struct A {};

Foo foo2;

你的程序生病了 .

但是,在单文件的情况下:

struct A;

template class Foo {

enum{ value = is_complete::value };

};

Foo foo; // note A is incomplete here

struct A {};

Foo foo2; // ill-formed

你的代码很好 . 在给定的编译单元中, Foo 有一个实例化点;第二个是对第一个实例化的引用 .

一个和两个文件的versoins几乎肯定会在C编译器中编译,没有错误或警告 .

有些编译器会记住模板实例化,甚至从一个编译单元到另一个编译单元; Foo 即使在创建 foo2 之后也会 ::value 为 false (带有完整的 A ) . 其他人在每个编译单元中都有两个不同的 Foo ;它的方法将被标记为内联(并且是不同的),类的大小可能不同意,并且您将获得错误的程序问题 .

最后,请注意 std 中的许多类型要求它们的模板参数在旧版本的C中完整(包括c++11:“17.6.4.8其他函数(...)2 . 在以下情况下效果未定义:( ... )特别是 - 如果使用不完整类型(3.9)实例化模板组件时的模板参数,除非特别允许该组件“ - 从boost不完整的容器文档中复制” . 具体而言, std::vector 曾经要求 T 完整 .

[vector.overview] / 3

如果分配器满足分配器完整性要求17.6.3.5.1,则在实例化向量时可以使用不完整类型T.在引用向量特化的任何成员之前,T应该是完整的 .

现在,甚至在c++17之前,大多数 std::vector 的实现都没有用 T 完成,直到你尝试使用一个方法(包括它的许多构造函数或析构函数),但标准声明 T 必须完整 .

这实际上妨碍了一些无用的代码,比如有一个函数类型返回它自己的type1的向量 . Boost有一个库来解决这个问题 .

template

struct Foo {

Foo() {

new T;

}

};

Foo::Foo() 的主体仅被实例化"when called" . 所以 T 缺乏完成没有影响,直到 Foo::Foo() 被调用 .

Foo foo;

^^将无法使用非完整 A 进行编译 .

using foo_t = Foo;

^^将编译,并且不会导致任何问题 .

using foo_t = Foo;

struct A {};

foo_t foo;

也没问题 . 当我们尝试构造 foo_t 时, foo_t::foo_t 的主体被实例化,并且所有定义都匹配 .

1你能说状态机转换功能吗?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值