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

c++ - 使用 C++11 可靠地检查类模板是否已实例化?

过去可以使用一些 C++ 编译器来检查模板类型是否已经被实例化,以便以下程序语法编译时不会出错:

“魔法”就在这个问题的解决方案中:

编译时模板实例化检查

但是 - 这不再适用于最近的 GCC 和 Clang 版本(Godbolt.org)。此外,为该问题编写已接受答案的用户已离开 SO 并且不会更新它......

所以,我的问题是:是否可以可靠地检查类/结构模板是否已为某种类型实例化?

笔记:

  • 寻找使用 C++11 的解决方案 - 不是以后的任何事情。
  • “这是不可能的”是一个有效的答案,但 - 只有当你能证明它是合理的。
  • 相关:这个问题
  • 如果它更容易,您可以假设该类可以实例化;但最好不要。
0 投票
1 回答
132 浏览

c++ - 检查默认删除的函数模板是否明确专门用于特定类型?

(这个问题已经过大量编辑,抱歉。)

假设我有几个非常量函数模板,默认被删除:

并且有一些明确的特化作为一般情况删除的例外。

我想编写代码(例如特征类?),给定这些函数之一的标识符和类型 T,在编译时检测指定的函数是否明确专门用于类型 T。代码需要通用的,即不是每个功能的单独检测器。

笔记:

  • 寻找 C++11 解决方案。
  • 我们可以假设默认情况下会删除指定的函数——如果有帮助的话。
  • 理想情况下,它会喜欢instantiation_exists<decltype(foo), foo, int>::valueinstantiation_exists<int>(foo, tag<int>)instantiation_exists(foo, tag<int>)或类似的东西。

编辑: @Jarod42 在对这个问题的早期版本的评论中写了一个SFINAE 示例,该版本是关于每个单功能检测器的。我尝试使用模板模板参数对其进行概括/泛化:

但那是一种洗涤(Coliru)。

0 投票
0 回答
22 浏览

c++ - 导出的模板类实例化导致 msvc 编译错误

我正在尝试编译类似于以下代码的代码,它是我尝试使用 MS Visual Compiler 编译的库 dll 的一部分:

编译失败并出现以下错误:

我无法找出这个简单的代码有什么问题。如果我删除__declspec(dllexport),它会完美地编译和执行。

预先感谢您的帮助。

0 投票
1 回答
64 浏览

c++ - 是否可以使用单个定义同时定义函数的 const 和常规版本?(使用模板、自动、decltype 等)

假设我正在为单链表编写迭代器和 const_iterator。

假设我有以下课程:

我的问题是是否有可能以某种方式替换这些行

具有单个定义(可能使用模板参数 isConst)并由编译器推导出 const 说明符?当 isConst = true 时,我希望 * 成为 const T& operator*() const,并且在 isConst = false 时拥有两个版本。可能吗?如果是 - 那么怎么做呢?

0 投票
0 回答
54 浏览

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 中遇到过这个问题。这是一个错误,可以在合理的现代版本中复制吗?是否有任何设置可能触发此行为?

0 投票
0 回答
61 浏览

c++ - 在不同的 .cpp 文件中使用相同的 C++ 模板是否会重复代码?

假设您template_function<T>()在其他两个 .cpp 文件(a_uses_template.cppb_uses_template.cpp)中使用相同的内容,它们都隐式地实例化了模板。

据我了解,这应该会导致代码重复,因为a_uses_template.cppb_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(具有一个显式实例化的变体)

0 投票
1 回答
281 浏览

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, /GFand/Gy是不行的。
    • 使用上面两行中的所有标志就可以了。

变通方法的变通方法(使用/Od):std::tuple_size<decltype(instantiate<int, double>())>在 .cpp 中调用内部虚拟函数。然后在头文件中声明虚拟函数。

0 投票
2 回答
67 浏览

c++ - 如果类是不完整的类型,为什么会编译?

在 Memory.h 我有:

在 main.cpp 我有:

即使 Foo 直到我粘贴到 Memory.h 之后才完全定义,这编译得很好。我对为什么会编译感到困惑。编译器粘贴到 Memory.h 后的等效代码在 main.cpp 中是不是这样:

???因为这不能编译,所以我收到错误:

'newAlloc' 标识符未找到 'newAlloc' 不是内存的成员

基本上它想要 Foo 的完整定义。如果我将 Foo 类定义放在 Memory 之上,那么它编译得很好。因此,鉴于我的第二个版本相当于模板实例化后的代码(是吗?)那么为什么第一个版本可以编译,而第二个版本不能?

我在 Visual Studio 2019 16.4.5

0 投票
1 回答
493 浏览

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>定义有效?!谢谢你。

0 投票
1 回答
48 浏览

c++ - C++ - 返回带有未知模板参数的模板

我想从可以保存许多不同类型数据的文件类型中加载图像:像素可以编码为floats、doubles、unsigned chars、chars(类似于 TIF 文件)。加载后我将对图像数据进行的所有处理都取决于加载的数据类型。我已经有一个函数,它可以在给定文件路径和数据类型的情况下从 C 中处理我的文件类型的外部库加载适当的数据:

我想要的是有一个“通用”加载器,我的程序的用户可以从中指定他们想要的任何类型的支持文件,它会加载它们并在运行时定义要返回的正确类型的模板:

有没有办法在 C++ 中做这样的事情?在那之前我已经处理了很多模板,但在这个特定的用例中没有。

快速编辑:当然,我还可以将所有加载的数据转换为具有最小/最大界限的内部格式(即,将所有像素数据转换为double具有除此之外的类型的最小/最大界限)。但我想尽可能保持数据不变