问题标签 [explicit-instantiation]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
614 浏览

c++11 - C++11 外部模板:我们在哪里真正需要它们?

在 C++03 中,我们有模板显式实例化定义( template class Foo<int>),它强制实例化模板类。

在 C++11 中,我们有模板显式实例化声明( extern template class Foo<int>),它应该防止模板类的隐式实例化。(类模板实例化

我试图模拟我实际上需要显式实例化声明以减少编译时间的情况。但我不能。看起来没有这个功能一切正常(或不使用它)。

这是一个例子:

结果取决于我是否评论 ( extern template class Foo<int>;) 行。

这是两个 *.obj 文件的符号:

转储箱 /SYMBOLS test1.obj

011 00000000 UNDEF notype () 外部 | ??0?$Foo@H@@QAE@H@Z (public: __thiscall Foo::Foo(int))'

012 00000000 UNDEF notype () 外部 | ?get@?$Foo@H@@QBEHXZ (public: int __thiscall Foo::get(void)const )

013 00000000 SECT4 notype () 外部 | ?baz@@YAXXZ (void __cdecl baz(void))

...

转储箱 /SYMBOLS Foo.obj

017 00000000 SECT4 notype () 外部 | ??0?$Foo@H@@QAE@H@Z (public: __thiscall Foo::Foo(int))

018 00000000 SECT6 notype () 外部 | ?get@?$Foo@H@@QBEHXZ (public: int __thiscall Foo::get(void)const )

注意test1.objFoo<int>::Foo<int>(int)int Foo<int>::get(void)const标记为UNDEF的内容,这意味着它们必须在其他地方解析(即 Foo 仅编译一次)。

尝试#2:

如果我在 Foo.h 文件中定义完整的模板(没有明确的实例化定义),那么extern template没有帮助 - 模板编译两次(在 test1.cpp 和 test2.cpp 中)。

例子:

以下是符号转储:

转储箱 /SYMBOLS test2.obj

01D 00000000 SECT4 notype () 外部 | ??0?$Foo@H@@QAE@H@Z (public: __thiscall Foo::Foo(int))

01E 00000000 SECT8 notype () 外部 | ?get@?$Foo@H@@QBEHXZ (public: int __thiscall Foo::get(void)const )

01F 00000000 SECT6 notype () 外部 | ?bar@@YAXXZ (void __cdecl bar(void))

转储箱 /SYMBOLS test1.obj

01D 00000000 SECT6 notype () 外部 | ?baz@@YAXXZ (void __cdecl baz(void))

01E 00000000 SECT4 notype () 外部 | ??0?$Foo@H@@QAE@H@Z (public: __thiscall Foo::Foo(int))

01F 00000000 SECT8 notype () 外部 | ?get@?$Foo@H@@QBEHXZ (public: int __thiscall Foo::get(void)const )

在 Foo 提供的两个 *.obj 文件中。

所以我的问题是显式实例化声明可能有什么用处?或者也许我在测试中遗漏了一些东西?

我使用 VS2013 编译器。

0 投票
2 回答
192 浏览

c++ - 使用显式实例化声明删除反向指针会导致 std::bad_weak_ptr 异常

我开发了一些可以正确编译但在(调试)运行时失败的代码。我正在使用VS2015。

背景:我正在构建一个高级消息引擎。为了使新消息的编程添加可维护,在生产代码中,我花时间使用explicit initialization declarationC++ 构造来制作初始消息。这很有效,并且使新消息的制作变得千篇一律,更不用说将消息传递的维护减少到几乎没有。这是此功能的框架代码:

此代码编译并运行。

但是我在真实代码中的派生对象是共享的ptrs。因此,我将此功能添加到代码中。请注意,我正在this使用以下构造获取派生类的 ptr enable_shared_from_this

此代码编译。但是,它没有运行,并且在 D1 构造函数中,它以异常 std::bad_weak_ptr 中断。

我试图将共享 ptrs 更改为弱 ptrs,但没有成功。有人看到问题了吗?

编辑1:根据@pat 的观察,shared_from_this()构造函数不可调用,请参阅下面的修改后的代码,现在可以编译并运行:

编辑 2:下面的代码是对我原始帖子代码的重写,并建立在 @pat 的答案之上。以下是更改的内容:显式实例化声明 (EID) 已移至其派生类。B 不再尝试引用派生对象。这是一个明显的错误。作为后向指针的 weak_ptr 被一个简单的后向 ptr 取代(就像原型中的情况一样)。泄漏没有问题,因为派生对象(D1 和 D2)完全拥有该对象。(在生产代码中,成员类型是共享的 ptrs 以防止泄漏。)

当添加任意数量的 EID 时,代码维护复杂性从指数(如原型中的情况)降低到线性的设计不变量已经实现。

0 投票
0 回答
1035 浏览

c++ - C++ 模板显式实例化声明:最佳实践

我的问题是我们应该如何以正确的方式使用模板显式实例化声明

假设我们有一些模板类template<class T> Foo

这是我如何处理此功能的想法:

我们将模板声明放在Foo.h文件中,将实现放在Foo.inl文件中,将其包含Foo.inl在文件末尾,Foo.h放在. 此外,我们应该在例如文件中使用显式模板实例化定义(当然我们也应该在这个 cpp 文件中包含)。extern template class Foo<int>;#include "Foo.inl"Foo.cppFoo.h

如果我们做所有这些事情,我们会得到一个错误:我们不能在显式模板实例化声明之后使用显式模板实例化定义。好的,让我们将模板声明和放在单独的文件中,并将其包含在. 最终我们得到了这个:#include "Foo.inl"Foo.hppFoo.cpp

Foo.hpp

Foo.inl

Foo.h

Foo.cpp

并使用此模板,如下所示:

测试1.cpp

Foo 太多了,你不觉得吗?你如何处理这个问题?

对不起我的英语不好。

更新:

问题不是关于显式模板实例化定义或模板代码本身的配置方法,而是关于显式模板实例化声明的使用以及如果我们尝试使用它会产生“文件地狱”。

0 投票
1 回答
330 浏览

c++ - 显式实例化可变参数构造函数:模板 ID 不匹配任何模板声明

我正在尝试显式实例化可变参数构造函数。这个打印所有参数的最小示例导致我在带有 GCC 5.3 的 64 位 Win 7 上的 MinGW-w64 上看到的相同错误。

0 投票
1 回答
405 浏览

c++ - 为什么函数模板的显式实例化不能使用 inline 或 constexpr

参考cppreference 关于函数模板的部分

函数模板或类模板的成员函数的显式实例化不能使用 inline 或 constexpr

这些主题inlineconstexpr似乎是独立且不相关的。为什么会有这个限制?

0 投票
2 回答
975 浏览

c++ - 非模板类的模板构造函数的C++显式实例化

我正在开发一个使用 pimpl idiom 的 C++ Fraction 类,我的公共标头类似于(正在进行中)

代码:

我可以使用成员的显式实例化在我的 cpp 文件中进行正确的专业化(例如,比较运算符重载)

部分代码

但是当我想对构造函数做同样的事情时,我遇到了一些 VS2015 编译器错误:

我收到构建错误(法语):

fraction.cpp 第 156 行是:

英文错误(大约翻译):

我已经测试了显式实例化的一些变体,但我找不到解决方案。我希望这是标准允许的吗?


编辑:为了回答 Sam Varshavchik 的评论,cpp 类以以下形式集成了 Fraction 类的私有实现:

在这里,不需要模板的显式特化,因为它是一个 .hpp 类样式。


解决方案(感谢Constructor是(如此明显的)解决方案)

只是:

  • 替换impl<N,D>by impl
  • 删除<int, int>模板中的显式实例化。
0 投票
0 回答
2223 浏览

c++ - 类模板的成员函数模板的显式实例化

假设我的头文件中有一个带有成员函数模板的类模板。

我在 .cpp 中有 foo 的实现:

如果我想在 .cpp 文件中为 int 和 float 显式实例化我的类和成员函数,我需要类似的东西:

如果我开始有很多类型的 T 和 U,这会变得有点冗长。有没有更快的方法来做到这一点并且仍然在 cpp 文件中显式实例化模板?我在想像

但它不起作用。

0 投票
1 回答
484 浏览

c++ - 我们什么时候需要显式地实例化一个模板函数?

假设我们有一个模板函数:

由于编译器在模板实参推导过程中不进行任何隐式类型转换,我们可以通过max(2, 5.5)以下两种方式调用:

  1. 使用铸造:max(static_cast<float>(2), 5.5f);
  2. 使用显式模板实例化:max<float>(2, 5.5);

第二种情况对我来说是有意义的,但是我们什么时候以下面给出的方式进行显式模板实例化(实例化而不调用char类型的函数)max

我们能从中获得什么?

0 投票
1 回答
911 浏览

c++ - 模板显式实例化是否适用于前向声明类型?

如果我有一个在 .cpp 文件而不是 .h 文件中定义了某些方法的模板类,我可以使用显式实例化来让编译器避免未解析的外部变量。

但是,如果使用前向声明的类型声明显式实例化,它会起作用吗?

如果A最终未定义Template<A>且未使用,它会起作用吗?

0 投票
1 回答
367 浏览

c++ - 显式模板实例化和转发引用

最近,我正在和学生讨论使用转发引用的模板限制类型的可能性。我知道用or来比较类型,但我们也谈到了显式模板实例化is_samestatic_assertenable_if

以下示例适用于 GCC:

fh:

f.cpp:

主.cpp:

我不是显式模板实例化方面的专家,所以我只是想知道这样的解决方案是否可移植/符合标准。(请不要问我用例,我没有。对我来说,这纯粹是一个学术问题。

更新

我对显式实例化(<int>(int&&)<int&>(int&))的格式也有点困惑,但我猜它是由模板推导给出的,可能是引用折叠规则。