问题标签 [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++ - 使用 C++11 可靠地检查类模板是否已实例化?
c++ - 检查默认删除的函数模板是否明确专门用于特定类型?
(这个问题已经过大量编辑,抱歉。)
假设我有几个非常量函数模板,默认被删除:
并且有一些明确的特化作为一般情况删除的例外。
我想编写代码(例如特征类?),给定这些函数之一的标识符和类型 T,在编译时检测指定的函数是否明确专门用于类型 T。代码需要通用的,即不是每个功能的单独检测器。
笔记:
- 寻找 C++11 解决方案。
- 我们可以假设默认情况下会删除指定的函数——如果有帮助的话。
- 理想情况下,它会喜欢
instantiation_exists<decltype(foo), foo, int>::value
或instantiation_exists<int>(foo, tag<int>)
或instantiation_exists(foo, tag<int>)
或类似的东西。
编辑: @Jarod42 在对这个问题的早期版本的评论中写了一个SFINAE 示例,该版本是关于每个单功能检测器的。我尝试使用模板模板参数对其进行概括/泛化:
但那是一种洗涤(Coliru)。
c++ - 导出的模板类实例化导致 msvc 编译错误
我正在尝试编译类似于以下代码的代码,它是我尝试使用 MS Visual Compiler 编译的库 dll 的一部分:
编译失败并出现以下错误:
我无法找出这个简单的代码有什么问题。如果我删除__declspec(dllexport)
,它会完美地编译和执行。
预先感谢您的帮助。
c++ - 是否可以使用单个定义同时定义函数的 const 和常规版本?(使用模板、自动、decltype 等)
假设我正在为单链表编写迭代器和 const_iterator。
假设我有以下课程:
我的问题是是否有可能以某种方式替换这些行
具有单个定义(可能使用模板参数 isConst)并由编译器推导出 const 说明符?当 isConst = true 时,我希望 * 成为 const T& operator*() const,并且在 isConst = false 时拥有两个版本。可能吗?如果是 - 那么怎么做呢?
c++ - Qt Creator 不会在具有多个实例化的模板代码中的断点处停止
我在 Qt Creator 中遇到了一个看起来像错误的问题,但在提交票证之前,我希望收集更多信息:是否可重现、已知(可能已经有修复)等。
我正在使用基于 Qt 5.14.0 (MSVC 2017) 的 Qt Creator 4.11.0。如果我将断点添加到具有多个实例化的模板代码中,则默认情况下此断点永远不会触发。让我们创建一个简单的应用程序(例如控制台应用程序),定义一个 tempate 函数并在其中添加一个断点:
函数的实现无关紧要,重要的是我们只有一个实例化func<int>
。一切都按预期工作,但是如果我们再添加一个实例,就会发生一些变化:
现在我们有了func<int>
and func<long>
,这反映在断点视图中(Qt Creator 现在将断点扩展为 2 个子项,每个子项标识实例化的函数)。现在两个断点实例都没有被触发!
有趣的是,但如果我们在调用之前的某个位置func<T>
(在非模板代码中)再添加一个断点,调试器将在所有 3 个断点处停止。看起来它需要在第一站执行一些初始化。
这很烦人,因为我main
每次计划跟踪代码时都必须添加断点。我从未在过时的 Qt Creator 3.5.1 中遇到过这个问题。这是一个错误,可以在合理的现代版本中复制吗?是否有任何设置可能触发此行为?
c++ - 在不同的 .cpp 文件中使用相同的 C++ 模板是否会重复代码?
假设您template_function<T>()
在其他两个 .cpp 文件(a_uses_template.cpp
和b_uses_template.cpp
)中使用相同的内容,它们都隐式地实例化了模板。
据我了解,这应该会导致代码重复,因为a_uses_template.cpp
和b_uses_template.cpp
是单独编译的,所以template_function<T>()
会被实例化两次。
但是,如果我将代码更改为仅使用一个显式实例化,则生成的可执行文件会更大,而不是预期的更小。
这怎么可能?
主文件
a_uses_template.h
a_uses_template.cpp
以下是 template_function.h /.cpp 的两个变体,第一个 with 与两个隐式实例一起使用,然后是两个包含一个显式实例的文件。
template_function.h(具有两个隐式实例的变体)
template_function.h(具有一个显式实例化的变体)
template_function.cpp(具有一个显式实例化的变体)
c++ - 使用 decltype 显式实例化函数:适用于 g++ 但不适用于 Visual C++
此代码在 G++ 上运行,但不在 Visual C++ 上运行。
这是来自 Visual C++ 的错误:-
错误 C2206: 'foo': typedef 不能用于函数定义
激励:我不想为显式实例化重复函数签名。我从https://stackoverflow.com/a/28356212
修改了代码。
哪一个是错的?如何在 Visual C++ 中解决它?
当前的间接解决方法
一天后,这是我发现的最佳解决方法:https ://stackoverflow.com/a/50350144 。
foo.cpp
但是,在 Visual C++ 中,它仅在打开优化进行编译时才有效:-
Custom
或者Disabled(/Od)
不行。- 全部使用
/O1
,/O2
就/Ox
OK了。 - 没有任何
/Od
,/O1
,/O2
和/Ox
:-- 刚刚
/Og
好。 - 只是
/Oi
,/Ot
,/Oy
,/Ob2
,/GF
and/Gy
是不行的。 - 使用上面两行中的所有标志就可以了。
- 刚刚
变通方法的变通方法(使用/Od
):std::tuple_size<decltype(instantiate<int, double>())>
在 .cpp 中调用内部虚拟函数。然后在头文件中声明虚拟函数。
c++ - 如果类是不完整的类型,为什么会编译?
在 Memory.h 我有:
在 main.cpp 我有:
即使 Foo 直到我粘贴到 Memory.h 之后才完全定义,这编译得很好。我对为什么会编译感到困惑。编译器粘贴到 Memory.h 后的等效代码在 main.cpp 中是不是这样:
???因为这不能编译,所以我收到错误:
'newAlloc' 标识符未找到 'newAlloc' 不是内存的成员
基本上它想要 Foo 的完整定义。如果我将 Foo 类定义放在 Memory 之上,那么它编译得很好。因此,鉴于我的第二个版本相当于模板实例化后的代码(是吗?)那么为什么第一个版本可以编译,而第二个版本不能?
我在 Visual Studio 2019 16.4.5
c++ - 模板显式实例化如何工作以及何时工作?
这是 C++ 入门第 5 版中的一个练习:
“练习 16.26:假设NoDefault
是一个没有默认构造函数的类,我们可以显式实例化vector<NoDefault>
吗?如果没有,为什么不呢?”
这是我的猜测:
是的,我们可以实例化它:
代码工作正常,但如果我取消注释 main 中的行,我会得到预期的错误,因为Bar
它不是默认可构造的。
如果我使用与Bar
元素类型相同的类,std::vector
则它不起作用:
那么为什么我的
Foo<Bar>
实例化有效但无效vector<Bar>
呢?在我看来,
vector<Bar>
不工作是合乎逻辑的,因为显式的实例化定义实例化了类模板的所有成员(甚至是未使用的成员);在这个例子中,其中的默认构造函数Foo<Bar>
意味着ctor
其元素类型的默认值Bar
;后者不提供;毕竟Foo<Bar>()
通常被声明为已删除的成员函数,因为x_
没有默认构造函数。所以我不知道为什么Foo<Bar>
定义有效?!谢谢你。
c++ - C++ - 返回带有未知模板参数的模板
我想从可以保存许多不同类型数据的文件类型中加载图像:像素可以编码为float
s、double
s、unsigned char
s、char
s(类似于 TIF 文件)。加载后我将对图像数据进行的所有处理都取决于加载的数据类型。我已经有一个函数,它可以在给定文件路径和数据类型的情况下从 C 中处理我的文件类型的外部库加载适当的数据:
我想要的是有一个“通用”加载器,我的程序的用户可以从中指定他们想要的任何类型的支持文件,它会加载它们并在运行时定义要返回的正确类型的模板:
有没有办法在 C++ 中做这样的事情?在那之前我已经处理了很多模板,但在这个特定的用例中没有。
快速编辑:当然,我还可以将所有加载的数据转换为具有最小/最大界限的内部格式(即,将所有像素数据转换为double
具有除此之外的类型的最小/最大界限)。但我想尽可能保持数据不变