问题标签 [template-specialization]
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++ - 如何让编译器使用正确的模板特化?
考虑以下我的代码的简化版本。我有一个模板类A
、一个模板函数和一个专门用于处理诸如orFill
之类的基本类型的函数,以及另一个可以处理的专门化:int
char
A
虽然我很惊讶编译器设法将参数与正确的模板特化相匹配,但这工作得很好。
问题出在一些typedef
易于使用的 s 上A<x>
。这是一个简化版本:
编译器没有检测到该类型A12
实际上是A<12>
并且使用了错误的函数特化,该函数无法编译,因为 istringstream 无法将 o 解析perator>>
为A
.
我怎样才能让它使用正确的模板专业化?
c++ - 理解(简单?)C++ 部分模板专业化
注意:这似乎是一个问题的转贴:C++ - Overload templated class method with a partial specilization
我将 C++ 模板专业化遇到的问题归结为一个简单的案例。
它由一个简单的 2 参数模板类组成Thing
,我想专门Thing<A,B>::doSomething()
针对B=int
.
不幸的是,g++
退出并出现错误:
编译器clang++
有点冗长,但有同样的问题:
我已阅读并理解不允许对函数进行部分模板专业化 - 但我认为Thing
在这种情况下我部分专业化了类。
有任何想法吗?
我做了什么:一种解决方法,由接受的答案提供的链接确定:
c++ - 消除 C++ 中的递归模板实例化
我想定义一个可以在不同位置(在文件范围内)调用的宏,以便创建执行某些操作的函数。(在下面的示例中,函数只是打印一条消息,但当然我的真正意图是做一些其他有用的事情。)挑战是我想要一些“管理器”功能(在我的示例中它只是main()
) 以某种方式成功地使它们全部被调用(以任何顺序),而没有任何代码依赖于宏调用(当然,宏调用本身除外)。我的意思是,一旦文件被写入,另一个程序员将能够在不同的地方插入一些新的宏调用或删除一些现有的调用,并且代码仍然可以工作而无需任何进一步的更改。我意识到这可以使用静态对象来完成,但我想探索一种不同的方法。我将使用一些模板技巧和__LINE__
单调递增的事实。
这打印
正如预期的那样。
该解决方案有一些缺点。
- 不能
REGISTER
在同一行调用两次。 #line
如果被玩会坏掉。- 在所有调用
REGISTER
. - 由于递归实例化而增加了编译时间。
- 除非所有的“虚拟”实例
f
都被内联,否则运行时的调用堆栈深度将与管理器之间START_REGISTRATION;
和f<__LINE__>();
管理器中的行数一样大。 - 代码膨胀:除非所有的“虚拟”实例
f
都被内联,否则实例的数量同样会很大。 - 过度的实例化递归深度可能会达到编译器的限制(在我的系统上默认为 500)。
问题1-4 我真的不介意。问题 5 可以通过让每个函数返回一个指向前一个函数的指针来消除,并让管理器使用这些指针迭代地调用函数,而不是让它们相互调用。可以通过创建一个类似的类模板构造来消除问题 6,该构造能够为每次调用REGISTER
在上一次调用中实例化了什么函数,因此只实例化实际执行某些操作的函数。过多的实例化将从函数模板转移到类模板,但类实例化只会对编译器造成负担;他们不会触发任何代码生成。所以我真正关心的是问题 7,问题是:有没有办法重组事物,以便编译器迭代而不是递归地进行实例化。我也完全接受不同的方法(除了那些涉及静态对象的方法)。一个简单的解决方案是在经理之前将所有注册组合在一起(或添加一个STOP_REGISTRATION
宏来结束注册块)但这会破坏我的目的的重要部分(在定义它的代码旁边注册东西)。
编辑: 有一些有趣的建议,但恐怕我并没有明确说明我希望实现的目标。我对两件事真的很感兴趣:解决提出的问题(即,没有静态,每个注册单行,添加/删除注册时没有额外的更改,虽然我没有这么说,但只有标准 C++ --- 因此,没有提升)。正如我在下面的评论中所说,我的兴趣更多是理论上的:我希望学习一些新技术。因此,我真的很想专注于重组事物,以便消除(或至少减少)递归,或者找到满足我上面列出的约束的不同方法。
编辑 2: MSalter 的解决方案向前迈出了一大步。起初我以为每次注册都会产生排队的全部成本,但后来我意识到一个函数当然只能实例化一次,所以在实例化方面我们付出与线性搜索相同的代价,但是递归深度变为对数。如果我能解决它,我将发布一个完整的解决方案,消除问题 5-7。不过,看看它是否可以在恒定的递归深度中完成,最好的情况是,实例化的数量与调用的数量成线性关系(a-la 提升解决方案)。
编辑3: 这是完整的解决方案。
c++ - 代码重复和模板特化(当特化函数有不同的返回类型时)
我正在创建一个模板类D<N>
,它有一个返回不同类型的方法(在本例中为 operator()),具体取决于 N 的值。
我只能通过创建两个单独的类声明来完成这项工作,但这是以大量重复代码为代价的。我还尝试创建一个通用基类来将通用的东西放入其中,但我无法让构造函数正确继承,也不知道这会是多么地道......
如何让我的代码看起来更好看?
c++ - 如何在 C++ 中通过其值类型专门化迭代器?
是否可以通过它来专门化一个迭代器模板参数value_type
?
我有一个具有以下原型的功能。
如果InputIterator::value_type
是,我想特别处理SomeSpecificType.
c++ - c++模板规范和重载的解析
我已经阅读了Why Not Specialize Function Templates,经过一些实验,我发现了一件有趣的事情。这是main.cxx:
有趣的是:如果我保留声明部分的注释,则行为就像文章所说的那样,即如果 int* 版本的定义在其定义之前,则将使用 T* 版本,反之亦然。但是,如果取消注释声明块,无论我在定义或声明中使用哪种顺序,都只会调用 int* 版本。我的问题是这个声明是如何影响决议的?
有任何想法吗?我在 x86_64-redhat-linux 上使用 g++ 4.2.2
编辑:在看到 AProgrammer 的回答后简化这个问题
c++ - C++模板偏特化题
我在使用以下代码时遇到了编译问题:
错误消息是(在标记为“这里”的行上):
(当然,我已经包含了来自 std 的向量!)。有什么建议吗?我摆弄了一段时间,但我已经到了可以使用一些帮助的地步:-)我需要部分专门化初始模板声明,以便我可以让编译器根据实际类型切换实现容器 C(将有一个 is_in 用于集合,一个用于向量,一个用于范围......,每次使用不同的算法)。
谢谢!
c++ - 当我在 C++ 中对类模板进行完全专业化时,为什么不必定义相同的成员?
我很惊讶地发现以下编译:
为什么允许这样做?class SomeCls<int>
不需要方法似乎是错误的void UseT(T t)
。我确定我在这里错过了专业化的重点(我不是 C++ 专家)。有人可以启发我吗?
c++ - C ++中的显式专业化
我正在阅读 Primer C++ > 函数冒险 > 模板 > 显式专业化。
为了说明显式专业化的原因/用途,我们举例说明了一个案例。考虑一个可以交换任何类型(int、double、struct等)的交换模板函数(我认为代码很明显,所以这里不需要写)
但是有一个特定的结构(称为作业),您只想交换其中的两个成员,而让其余成员保持原样。您将需要不同的定义,因此您必须进行显式专业化。
在同一节中有这样的声明:-“专业化覆盖常规模板,非模板函数覆盖两者。” 为什么不为此用途创建一个(常规)功能?那么常规/非模板会覆盖模板吗?
如果我的解决方案是正确的,那么什么是显式专业化的好例子?
c++ - 空参数包的模板特化
我有一个可变参数模板函数,它调用自身来确定列表中的最大数字(由模板化参数构成)。我正在尝试对参数包为空时进行专门化,因此我可以只返回列表前面的数字,但我不知道该怎么做。我刚刚熟悉可变参数模板和模板专业化,但这是我目前所拥有的:
但是,这会产生以下错误:
我也试过这个,只是想看看它是否可以工作(尽管它随机将数字 0 引入列表,因此它永远不会返回小于 0 的数字):
但是,除了上面提到的错误之外,我还收到了这个错误:
那么我应该怎么做才能让它工作呢?
我正在使用带有-std=c++0x
标志的 g++ 4.5.2。