问题标签 [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.
c++ - 编译器如何生成正确版本的模板函数,其参数在运行时知道?
我试图用参数声明一个模板类,哪些类型在运行时会被清除,并且想看看代码编译是否期望它不会,因为模板是在编译时实例化的,而这里的参数是在运行时定义的。但它编译并正常工作。
我有:
如果输入为 67,它会打印“C”,因此它可以正常工作。
使用的向量成员是否在运行时实例化?如果不是,编译器如何实例化向量成员?
c++ - 为什么要实例化此模板类特化?
在模板类的特化中,我调用了一个不应编译的函数,但在我看来,这并不重要,因为我false
作为模板参数传递并且编译器不应该首先实例化该类:
如果我传递参数,为什么会innerStruct<true>
被实例化并且编译器会尝试调用?underlying_type
false
对我来说非常令人困惑,我可以std::underlying_type_t
通过向 中添加另一个模板参数来使其按照我想要的方式运行(即,让编译器忽略对 的调用)innerClass
,在这里我添加一个U
:
第一个例子和第二个例子有什么区别?innerStruct<true>
如果在第一个示例中我只调用了模板专业化,则实例化了哪些业务innerStruct<false>
c++ - 为什么 decltype 不实例化这个递归函数原型?
我创建了以下代码来创建从 0 到 N 的数字序列。我知道有像这里这样具有 O(log N) 实例化深度的更好方法,但这不是重点。
在 cppinsights 上运行代码显示 onlymethod
已实例化,这只是为了让我看到数字 0 到 N 确实正在生成。我很惊讶,因为我认为我也会看到实例化makeNums
。编译器如何在没有其他实例的情况下创建此索引序列?
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
c++ - 如何使用“if constexpr”正确实现“operator()”,以便它与 std::generate 一起使用?
我正在尝试编写一个类,该类将使用容器具有的类型填充随机数的容器:
但是这里某处发生了错误,因为当我调用 std::generate 时,我得到了很多错误:
我认为这可能是因为if constexpr但如果只是离开:
然后仍然返回相同的错误。这是我得到的错误列表:
函数调用如下:
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
,这是检查地图文件的样本以得出这个结论
地图文件样本
c++ - 何时实例化模板?
事实上 atemplate
在使用之前不会被实例化,例如,如果我有这个类模板:
那么模板究竟是什么时候被实例化的呢?
那么是在声明
Pow<int>
时实例化的吗?func(Pow<int>)
如果我没有使用
Pow<int>
inmain()
那么它是否被实例化了,因为它使用 infunc
作为其参数的类型?
c++ - 如果一个函数定义有一个类模板类型的参数并且没有使用它(它的成员),那么它是否被实例化?
从我在这里发布的上一个示例中,关于何时template
实例化?,我得到的答案是只有在使用模板时,编译器才会实例化它。但是看看这个例子:
正如你所看到的,我已经声明了一个显式的模板实例化
Pow<int>
,但还没有定义它。该程序运行良好,不会抱怨缺少Pow<int>
!在上一个主题中,如果我使用模板类型作为函数定义(而不是声明)的参数类型,那么模板会被实例化,但在这里你可以看到:定义了成员函数和
Foo::fn(Pow<int>)
普通函数函数bar(Pow<int>)
但编译器不会抱怨Pow<int>
?!!!如果我取消注释上述函数中的行,程序将无法编译。那么这是否意味着
Pow<int>
在函数定义中用作函数参数和像 in 中的成员数据时不实例化Foo::Pow<int> pi{};
?我觉得很混乱:
主要:
c++ - 为什么编译器实例化模板而我要求他不要?
我想防止编译器使用extern template
.
以下片段按预期工作(static_assert
不触发):
但是有了这个,编译器似乎试图实例化模板函数,因为static_assert
确实触发了:
有了这个,static_assert
也会触发,而我希望它不会:
在我的实际情况中,我想加快编译时间,但我观察到编译有 的翻译单元,extern template ...
与这些模板相关的符号不会出现在.o
文件中(用 看nm
),但它们实际上是编译的。 ..(我通过使用 clang-ftime-trace
和 with观察重要的编译时间来检查这一点templight++
)。
为什么似乎extern template
没有按预期工作?
谢谢!