当前位置: 首页 > 知识库问答 >
问题:

当包装到模板中时,不完整类型的新文件将编译

蒋高扬
2023-03-14

考虑这个代码,有一个明显的编译错误:(1)

struct A;
struct B {
  B() { new A(); } // error: allocation of incomplete type 'A'
};

使用唯一\u ptr也不会有任何帮助:(2)

struct A;
struct B {
  B() { std::make_unique<A>(); } // error: due to ~unique_ptr()
};

然后(令我大吃一惊)我发现,这将编译:(3)

struct A;
struct B {
  B() { std::make_unique<A>(); }
};
struct A {}; // OK, when a definition is added **below**

然后我检查了一下,这是否也有助于new——否:(4)

struct A;
struct B {
  B() { new A(); } // error: allocation of incomplete type 'A'
};
struct A {};

我认为它与模板s有关,事实上:在模板中包装新的,编译:(5)

template <typename T> 
T* my_new() { return new T(); } // OK, when wrapped in template
struct A;
struct B {
  B() { my_new<A>(); }
};
struct A {};

为了完整起见,删除A的定义会再次引发一个错误:(6)

template <typename T> 
T* my_new() { return new T(); } // error: allocation of incomplete type 'A'
struct A;
struct B {
  B() { my_new<A>(); }
}; 
// do note: definition of A removed

这是怎么回事?据我所知,编译器必须知道A的大小/定义才能分配它,因此仅仅声明它是不够的。此外,我认为,定义必须先于分配。

这似乎是正确的,当直接使用new时(1,4)。但是当new被包装时,很明显我弄错了(2,3,5,6)。

到目前为止,我发现的可能解释如下:

  • 对已完成类型的检查延迟到模板实例化发生。我认为这是正确的,但在我的例子中,直接使用newa()调用myu new

为什么4被认为是不正确的,而5编译(或者5只是错误地编译了未定义的行为[但是3也必须有缺陷,对吗?])?

btw:通过clang-3.5.0和g-4.9.2测试


共有1个答案

储仲渊
2023-03-14

§14.6.4.1[temp.point]/p1,8,强调我的:

1对于函数模板专用化、成员函数模板专用化或类模板的成员函数或静态数据成员专用化,如果专门化是隐式实例化的,因为它是从另一个模板专门化中引用的,并且从中引用它的上下文取决于模板参数,那么专门化的实例化点就是封闭专门化的实例化点。否则,此类专门化的实例化点将紧跟在引用该专门化的命名空间范围声明或定义之后。

8函数模板、成员函数模板、或类模板的成员函数或静态数据成员的专门化可以在翻译单元内具有多个实例化点,并且除了上述实例化点之外,对于在翻译单元内具有实例化点的任何此类专门化,翻译单元的末端也被视为实例化点。类模板的专门化在翻译单元中最多有一个实例化点。任何模板的专门化都可能在多个翻译单元中有实例化点。如果根据“一个定义”规则(3.2),两个不同的实例化点赋予模板专门化不同的含义,则程序格式错误,无需诊断。

的实例化有两点my_new

 类似资料:
  • 问题内容: 有没有一种方法可以为使用模板的Cython包装的C ++类创建Python包装器?(即完全按照此处显示的内容进行操作,但要使用模板:http : //docs.cython.org/src/userguide/wrapping_CPlusPlus.html#create-cython- wrapper- class)。 我知道融合类型的变通方法(https://groups.googl

  • 首先是一些背景。正如C 17标准所述: [vector.overview]/3如果分配器满足分配器完整性要求17.6,则在实例化vector时可使用不完整类型T。3.5.1.T应在引用向量的任何结果特化成员之前完成。 我在本回购协议中尝试了3种方案(代码复制在底部): 包含不完整向量类型的类在同一头文件中声明(默认ctor/dtor)并定义 编译用b. h包括: 编译用b. h包括: 我的问题是,

  • 我想把C流包装在一个模板类中,这样所有 你能改变下面的代码,使它编译时不会改变整体意图吗? 我假设std::endl具有某种类型,因此被模板化方法“捕获”。

  • 是否有一种方法可以将Thymeleaf模板存储在与类相同的包中而不是或?例如,这样的结构: 为了实现这一点,我必须如何配置Spring和Thymeleaf?

  • 我试图通过Django制作一个新网站的主页。我的应用程序名称是“博客”,主页是home.html当我去http://127.0.0.1:8000/blog/home/时,我仍然收到错误模板不存在 我确保在settings.py中将“blog”添加到我的模板中,并在主目录中以及通过blog/templates/blog/home.html添加文件夹模板 myproject/blog/views.py

  • 尽管 PHP 不断升级为成熟的、面向对象的语言,但它作为模板语言 没有改善多少。编译型模板,比如 Twig、Brainy 或 Smarty,提供了模板专用的新语法,填补了这片空白。从自动转义到继承以及简化控制结构,编译模板设计地更容易编写,可读性更高,同时使用上也更加的安全。编译型模板甚至可以在不同的语言中使用,Mustache 就是一个很好的例子。由于这些模板需要编译,在性能上会带来一些轻微的影