问题标签 [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 回答
62 浏览

c++ - 编译器如何生成正确版本的模板函数,其参数在运行时知道?

我试图用参数声明一个模板类,哪些类型在运行时会被清除,并且想看看代码编译是否期望它不会,因为模板是在编译时实例化的,而这里的参数是在运行时定义的。但它编译并正常工作。

我有:

如果输入为 67,它会打印“C”,因此它可以正常工作。

使用的向量成员是否在运行时实例化?如果不是,编译器如何实例化向量成员?

0 投票
0 回答
41 浏览

c++ - 为什么要实例化此模板类特化?

在模板类的特化中,我调用了一个不应编译的函数,但在我看来,这并不重要,因为我false作为模板参数传递并且编译器不应该首先实例化该类:

如果我传递参数,为什么会innerStruct<true>被实例化并且编译器会尝试调用?underlying_typefalse

对我来说非常令人困惑,我可以std::underlying_type_t通过向 中添加另一个模板参数来使其按照我想要的方式运行(即,让编译器忽略对 的调用)innerClass,在这里我添加一个U

第一个例子和第二个例子有什么区别?innerStruct<true>如果在第一个示例中我只调用了模板专业化,则实例化了哪些业务innerStruct<false>

0 投票
0 回答
66 浏览

c++ - 为什么 decltype 不实例化这个递归函数原型?

我创建了以下代码来创建从 0 到 N 的数字序列。我知道有像这里这样具有 O(log N) 实例化深度的更好方法,但这不是重点。

链接到 cppinsights 中的代码

在 cppinsights 上运行代码显示 onlymethod已实例化,这只是为了让我看到数字 0 到 N 确实正在生成。我很惊讶,因为我认为我也会看到实例化makeNums。编译器如何在没有其他实例的情况下创建此索引序列?

0 投票
2 回答
149 浏览

c++ - 模板内定义的友元函数的实例化

这是对这个问题的跟进。最初的案例是另外一回事,但在我写一个糟糕的答案和 OP 澄清的过程中,结果证明我们可能需要语言律师的帮助来了解发生了什么。

在 Thinking in C++ - Practical Programming Vol 2 中,可以找到以下示例(我的意图,在此处在线):

他们继续解释(强调我的):

这个和前面的例子有一个重要的区别:这里的 f 不是模板,而是一个普通的函数。(请记住,在暗示 f( ) 是一个模板之前,尖括号是必需的。)每次实例化 Friendly 类模板时,都会创建一个新的普通函数重载,它接受当前 Friendly 特化的参数。这就是丹萨克斯所说的结交新朋友。[68] 这是为模板定义友元函数的最方便的方法。

到现在为止还挺好。当你考虑这个例子时,令人费解的部分是“这里的 f 不是模板,而是一个普通函数”+“每次实例化 Friendly 类模板时,都会创建一个新的、普通的函数重载”:

实例化foo<int>不会导致编译器错误!仅调用bar(x)原因(gcc 10.2):

普通函数的实例化?只有在调用函数时才会失败?这里发生了什么?

真的bar是普通功能吗?它仅在调用时实例化?为什么,当它是一个普通函数时?bar关于何时实例化实际发生了什么foo<int>(作者称其为“创建了一个新的、普通的函数重载”,不确定这应该是什么意思)?

对不起,这太令人费解了。请不要错过这个language-lawyer标签,我想知道为什么/标准的哪些部分使它如此,而不仅仅是什么。

PS:为了确保我再次检查,三个常见的嫌疑人在bar没有被调用时都编译了这个例子而没有重大抱怨:https ://godbolt.org/z/Wcsbc5qjv

0 投票
0 回答
58 浏览

c++ - 结构化绑定参数推导失败

我正在尝试扩展此答案以返回函数的结果以及 CPU 时间。这是我的代码:

我使用以下命令行编译它:

但我收到以下错误:

为什么这个初始化列表失败了?

更新: 按照Bob的提示,我设法通过将函数的返回值更改为这一行来返回一对:

这种方法有什么缺点吗?

0 投票
2 回答
97 浏览

c++ - 如何使用“if constexpr”正确实现“operator()”,以便它与 std::generate 一起使用?

我正在尝试编写一个类,该类将使用容器具有的类型填充随机数的容器:

但是这里某处发生了错误,因为当我调用 std::generate 时,我得到了很多错误:

我认为这可能是因为if constexpr但如果只是离开:

然后仍然返回相同的错误。这是我得到的错误列表:

函数调用如下:

0 投票
1 回答
51 浏览

c++ - 模板实例化导致函数膨胀

当我开始对 C++1x 特性进行更深入的试验时,我遇到了一些想法。例如,当有这个构造 template<unsigned int N> unsigned int functionForTest(const char (&a)[N]); 和它的用法时

functionForTest("Hello"); ---> const char [6]

functionForTest("Hello World") ---> const char [12];

然后 c++ 最终实例化了具有 2 个不同参数类型的 2 个函数,这意味着如果此函数以不同大小使用,则二进制大小会增加。那效率如何?它是编译器特定的吗?传统的类 C 数组和大小传递在这里不是更有效吗?

这就是我构建的方式g++ -std=c++17 -Xlinker -Map=output.map compilerDiffs.cpp -o test.exe,这是检查地图文件的样本以得出这个结论

地图文件样本

0 投票
2 回答
93 浏览

c++ - 何时实例化模板?

事实上 atemplate在使用之前不会被实例化,例如,如果我有这个类模板:

  • 那么模板究竟是什么时候被实例化的呢?

  • 那么是在声明Pow<int>时实例化的吗?func(Pow<int>)

  • 如果我没有使用Pow<int>inmain()那么它是否被实例化了,因为它使用 infunc作为其参数的类型?

0 投票
2 回答
67 浏览

c++ - 如果一个函数定义有一个类模板类型的参数并且没有使用它(它的成员),那么它是否被实例化?

从我在这里发布的上一个示例中,关于何时template实例化?,我得到的答案是只有在使用模板时,编译器才会实例化它。但是看看这个例子:

  • 正如你所看到的,我已经声明了一个显式的模板实例化Pow<int>,但还没有定义它。该程序运行良好,不会抱怨缺少Pow<int>!

  • 在上一个主题中,如果我使用模板类型作为函数定义(而不是声明)的参数类型,那么模板会被实例化,但在这里你可以看到:定义了成员函数和Foo::fn(Pow<int>)普通函数函数bar(Pow<int>)但编译器不会抱怨Pow<int>?!!!

  • 如果我取消注释上述函数中的行,程序将无法编译。那么这是否意味着Pow<int>在函数定义中用作函数参数和像 in 中的成员数据时不实例化Foo::Pow<int> pi{};

  • 我觉得很混乱:

  • 主要:

0 投票
1 回答
90 浏览

c++ - 为什么编译器实例化模板而我要求他不要?

我想防止编译器使用extern template.

以下片段按预期工作(static_assert不触发):

但是有了这个,编译器似乎试图实例化模板函数,因为static_assert确实触发了:

有了这个,static_assert也会触发,而我希望它不会:

在我的实际情况中,我想加快编译时间,但我观察到编译有 的翻译单元,extern template ...与这些模板相关的符号不会出现在.o文件中(用 看nm),但它们实际上是编译的。 ..(我通过使用 clang-ftime-trace和 with观察重要的编译时间来检查这一点templight++)。

为什么似乎extern template没有按预期工作?

谢谢!