问题标签 [template-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 投票
0 回答
200 浏览

c++ - C++:并行化模板实例化

我们有一个带有多个模板参数的大类。为了减少编译时间,我们已经在使用显式实例化。虽然这减少了包含头文件的每个人的编译时间,但编译 cpp 文件仍然非常慢。

有没有办法告诉编译器(这里:gcc 和 clang)并行实例化多个模板?

我们希望与将template class Foo<T1>;template class Foo<T2>;from 链接的问题放入两个不同的 cpp 文件具有相同的效果。

由于存在多种情况Foo和多个不同的实例化,因此必须为每个实例维护一个文件并不是最优的。此外,如上所示的显式实例化是由宏生成的。

0 投票
1 回答
173 浏览

c++ - 如果特化已经被隐式实例化,它是否会被隐式实例化?

标题中的问题已经很清楚了。更具体地说,请考虑以下示例:

此代码使用 GCC 和 Clang 编译

根据[temp.inst]/1

除非类模板特化已被显式实例化或显式特化,否则当在需要完全定义的对象类型的上下文中引用该特化或当类类型的完整性影响程序的语义时,类模板特化将被隐式实例化.

X<char>由于 被隐式实例化static_assert(!is_complete<X<char>>::type{}),这会生成不完整的类型。

然后,在 , 的定义之后X#1表明X<char>没有再次实例化(仍然不完整),而#2表明X<char>确实再次实例化(成为完整类型)。

如果特化已经被隐式实例化,它是否会被隐式实例化?#1为什么和之间有区别#2

欢迎对标准进行解释。

0 投票
1 回答
147 浏览

c++ - 根据实例化点期望不同的类型

我希望以下内容是不正确的 NDR,但似乎不是:-(

演示

注意:假设sizeof(T) != 0对完整性特征有效(因为没有类型可以具有sizeof(T) == 0,使用其他常量将强制为特征找到更好的名称:-))

它是代码的变体,如果它已经被隐式实例化,那么它是隐式实例化的吗?,其中程序已被声明为格式错误的程序,不需要诊断 (NDR),因为该方法 is_complete_helper<X>::test<X> 具有 2 个不同的含义,具体取决于实例化点。

似乎使程序格式错误的参考文献,但据我了解并非如此:

在假设的实例化中对这种构造的解释不同于在模板的任何实际实例化中对相应构造的解释。

函数模板、成员函数模板或类模板的成员函数或静态数据成员的特化可以在翻译单元内具有多个实例化点,并且除了上述实例化点之外,对于任何此类在翻译单元内有一个实例化点的特化,翻译单元的末端也被认为是一个实例化点。类模板的特化在翻译单元内最多有一个实例化点。任何模板的特化都可能在多个翻译单元中具有实例化点。如果根据单一定义规则,两个不同的实例化点赋予模板特化不同的含义,则程序是非良构的,不需要诊断。

我错了 ?或者不幸的是,这个程序是正确的。

0 投票
1 回答
253 浏览

c++ - clang 无法在模板实例化时生成默认的移动构造函数

以下代码(我无法制作更短的 MVCE)

单位.h

单位.cc

主.cc

无法在 clang 下编译(Apple LLVM 版本 9.0.0 (clang-900.0.39.2) -哪个 llvm 版本?),结果:

gcc(8.2.0)一切正常。经检查,gcc 似乎发出foo<int>::foo(foo<int>&&)in main.o,而 clang 未能完全发出它。

正确的行为是什么:移动构造函数应该用ordefault发出吗?这是一个已知的clang错误吗?unit.omain.o

有用的链接:https ://en.cppreference.com/w/cpp/language/class_template

0 投票
2 回答
151 浏览

c++ - 未实例化的模板的 C++ 标准要求

所以我尝试编译下面的代码,但它失败了(如预期的那样):

但是如果我删除这一行,编译器会编译它而不会出现任何错误(也可以预期,因为T类型是否有random_name()方法是未知的)。

似乎未使用(未实例化)的模板的诊断在某种程度上是实现定义的。但也许标准对这种情况有一些要求。例如,编译下面的代码是否符合标准而没有任何错误?

我试图在网站上搜索答案,但找不到任何相关问题。

0 投票
1 回答
614 浏览

c++ - “if constexpr”在模板之外有用吗?

我试图if constexpr完全理解。

我理解,如果if constexpr(expr)在模板中使用,并且expr依赖于模板参数,那么在实例化过程中,只有一个then/else分支将被实例化,另一个将被丢弃。

我有两个问题:

  • 是否真的,如果expr不依赖于模板参数,那么不会if constexpr(expr)丢弃任何分支?如果是,标准在哪里这样说?我看不出标准在哪里有例外,即丢弃仅在expr依赖时发生。
  • if constexpr在模板之外有用吗?如果是,这有什么用例?你能举一些例子来理解它的用处吗?
0 投票
2 回答
77 浏览

c++ - 从非实例化的上下文中引用特定的模板特化:实例化与否?

考虑以下示例

函数模板barbaz并且qux故意不实例化。

baz由于“明显”原因无法在 GCC 和 Clang 中编译的定义-S<void>S. 但是,在这种情况下哪种语言规则有效?

  1. 一方面,S<void>不依赖 的模板参数baz,成员访问要求它是完整的,这就触发了 的实例化S<void>,失败了。需要诊断。

  2. 另一方面,我们有“如果不能为非实例化模板生成有效的特化,则代码格式错误”的总括规则。这使得定义baz不正确。但是,不需要诊断。

更具体地说,我的假设是否正确(如 #1 中所表达),即上述S<void>来自非实例化的引用baz需要实例化S<void>? bar两个编译器都乐于接受 的 定义,它不实例化,这一事实支持了这一假设S<void>

但是,上述编译器对quxClang 抱怨的处理方式不同,而 GCC 则毫无抱怨地接受它。这是其中一个编译器中的错误吗?在这种情况下是否需要诊断?还是我假设#1 在这里工作是错误的?如果#2 是诊断的基础,那么编译器之间的差异是可以接受的。

0 投票
1 回答
104 浏览

c++ - 模板参数类型被编译器视为完整,但其定义尚不可见

假设我有以下代码片段:

如果我们取消注释第 (1) 行,我们会得到一个编译时错误“不完整类型 T”,并且似乎很清楚:class Bar实例化是由 (4) 启动的,而此时class Foo仅由 (3) 前向声明尚未由 (5) 定义。

但是如果第(1)行被注释掉了,那么这段代码编译没有错误,这让我很困惑:(4)是一个显式的模板实例化定义,它强制编译器生成void method()代码,第(2)行也应该生成同样的错误,因为 的定义Foo稍后在 (5) 中进行。

我错过了什么,为什么片段中的代码会编译?

更新:代码在 GCC 8.2.0 和 MSVC 19.16.27025.1 下编译,但在 Clang 7.0.0 下它给出“不完整类型”错误。

0 投票
1 回答
162 浏览

c++ - [temp.spec]/6 的起源故事?

[temp.spec]/6 内容如下:

通常的访问检查规则不适用于显式实例化或显式特化声明中的名称,但出现在函数体、默认参数、基本子句、成员规范、枚举器列表或静态数据中的名称除外成员或变量模板初始化程序。[注意:特别是,函数声明器中使用的模板参数和名称(包括参数类型、返回类型和异常规范)可能是通常无法访问的私有类型或对象。——尾注]

这条规则背后的动机是什么?哪个提案引入了它(或者它是古老的?),以及为什么?

0 投票
0 回答
35 浏览

c++ - 显式特化源文件中的类模板

我有一个带有一些模板别名的类模板。由于我只在模板上使用一组封闭的类型,我想专门化并显式实例化它们。我目前有这个:

我以为我需要一个extern template StringLiteral或一些东西,但这似乎有效。我能够StringLiteral在与专业化所在的TU完全不同的TU中使用。

我的问题是,这合法吗?如果是这样,为什么不需要显式实例化?我们无法在另一个 TU 中隐式实例化模板,因为我们没有构造函数的定义。

此外,使用模板别名进行专业化对我来说似乎很奇怪,对吗?