- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
许多容器类模板有一个以计数和样本元素作为参数的构造函数,以及另一个以一对输入迭代器为参数的构造函数。 insert
等其他方法表现出相同的模式。当模板用整数类型实例化时,天真的实现会遇到麻烦,并且用一对整数调用构造函数(或其他方法):它们的类型相等,输入迭代器方法将给出有效的参数类型推导,但随后无法编译。
我正在寻找一种优雅的方式来指定输入迭代器方法仅参与实际有效输入迭代器类型的(相等)参数类型的重载,或者至少不参与整数类型。我的印象是 SFINAE 是要走的路(但很高兴被告知不同),但是在阅读它时,坦率地说我不太了解规则,而且示例中提供的解决方案很难算得上优雅.
作为附带限制,我希望我的代码能够与具有不完整 C++11 支持的 gcc 4.6 兼容。值得注意的是,我想避免使用模板别名。这是我笨拙的尝试(简单的骨头):
#include <iterator>
#include <type_traits>
#include <vector>
template <typename I>
struct input_iter : public std::integral_constant<bool,
not std::is_integral<I>::value
and std::is_base_of
<std::input_iterator_tag
,typename std::iterator_traits<I>::iterator_category
>::value >
{};
template<typename T>
struct container
{
container (size_t count, const T& init);
template <typename InputIt,
typename = typename std::enable_if<input_iter<InputIt>::value>::type >
container (InputIt first,InputIt last);
};
typedef container<int> int_cont;
void f()
{ std::vector<int> v (5,3);
int_cont a1 (3u,6); // first constructor
int_cont a2 (3u,6); // first constructor
int_cont a3 (3,6); // first constructor
int_cont a4 (3,6); // first constructor
int_cont a5 (3,6); // first constructor
int_cont b(v.begin(),v.end()); // second constructor
}
这是一个 live example .类模板 input_iter
试图做一些冗余的事情:检查类型是否不是整数,然后它实际上是一个输入迭代器。最好我只使用第二部分,但这不起作用;在为 I
(没有 iterator_category
)尝试 int
时出现模板实例化错误,显然这不是 SFINAE。虽然我不明白为什么会这样,但我添加了第一部分以避免错误,使用 and
(&&
) 运算符的惰性,但显然徒劳无功。我实际上可以通过删除条件的第二部分来编译它,所以我真正的问题不是让它以某种方式工作,而是了解发生了什么。
我注意到一件奇怪的事情是 g++
只给出了一条错误消息,提到了 a3
的定义。因此,一方面,使一个参数无符号显然避免了尝试迭代器重载(即使另一个参数可以很容易地转换为无符号),另一方面重复 a3
的违规定义 a4
和 a5
不会重复错误消息(但如果有人修复 a3
定义,gcc
肯定会在 a4
定义)。另请注意,clang++
并未指向 a
变量之一的任何特定定义,尽管修复所有这些变量会使它保持沉默。
What am I doing wrong, and/or should obviously be doing differently?
最佳答案
在评论和更多实验的帮助下,我将尝试自己制定一个答案。
我收集到,如果替换失败发生在相关声明的“直接上下文”中,则替换失败只是 (SFI)NAE,这显然是 14.8.2;8 中使用的一个神圣的(但解释得不是很清楚)术语说“只有函数类型及其模板参数类型的直接上下文中的无效类型和表达式才能导致推导失败”。抛开构造方法实际上没有任何类型,示例中的失败/错误出现在尝试为(否则未使用的)第二个模板参数构造默认类型,但用派生整数类型代替 InputIt
时。进入片段typename std::enable_if...::type
.查找 std::enable_if
的 bool (非类型)模板参数的值本身是在“直接上下文”(类型替换)中执行的;前一段 14.8.2;7 对此很清楚(“表达式不仅包括常量表达式,例如出现在数组边界或作为非类型模板参数的表达式......”)。然而,计算该 bool 值需要形成类模板特化 input_iter<InputIt>
,这是一种辅助事件,不再在直接上下文中执行。事实证明,在该模板特化期间,执行了另一个模板特化,即 std::iterator_traits<InputIt>
;这也不在直接上下文中,但是这个事实在这里无关紧要,因为后者的特化永远不会失败。然而,生成的结构没有适当定义的 iterator_category
成员(member)时InputIt
被推导为整数类型,这导致特化 input_iter<InputIt>
在那种情况下失败。不在原始类型替换的直接上下文中,此失败使程序格式错误。
所以真正的罪魁祸首,将失败与 SFINEA 应用的上下文分开的元素,是特化 input_iter<InputIt>
,而 std::iterator_traits<InputIt>
只是间接参与。因此,可以通过删除由 input_iter
执行的类型派生来编译该示例。模板,并将 bool 表达式直接输入 enable_if
.因为我想避免使用模板别名,所以这需要(因为没有 bool 值模板这样的东西)忘记 input_iter
完全并将其包含的整个表达式移动到构造函数模板声明中,给出
template <typename InputIt,
typename = typename std::enable_if<not std::is_integral<InputIt>::value
and std::is_base_of
<std::input_iterator_tag
,typename std::iterator_traits<InputIt>::iterator_category
>::value>::type >
container (InputIt first,InputIt last);
std::is_integral
部分不是很有用,可以省略,只留下 std::is_base_of
部分。结果代码 compiles and runs correctly ,事实上即使是 gcc 4.6。这表明不管外表如何,一个人可以使用std::iterator_traits
与 SFINAE。当模板别名可用时,其中一个可用于提升 enable_if<...>::type
从构造函数声明中分离出来以使其看起来更有食欲,但没有它们我看不出如何做到这一点并仍然正确调用 SFINAE。
关于c++ - 如何使用 SFINAE 限制输入迭代器的重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25668966/
如果您有超过 1 个具有相同类名的(动态)文本框,并使用 jquery 循环遍历每个所述文本框,您是否可以假设每次选择文本框的顺序都是相同的? 示例: 文本框 1 值 = 1文本框 2 值 = 2文本
有人知道为什么这段代码无法顺利运行吗?它似乎不喜欢使用yield关键字进行迭代:我正在尝试从任何级别的列表或字典中挖掘所有数字(对列表特别感兴趣)。在第二次迭代中,它找到 [2,3] 但无法依次打印
我关于从 mysql 数据库导出数据并将其保存到 Excel 文件(多表)的创建脚本。我需要让细胞动态基因化。该脚本正确地显示了标题,但数据集为空。当我“回显”$value 变量时,我检查了数据是否存
我正在尝试在 Python 中运行模拟,由此我绘制了一个数组的随机游走图,给定了两个变量参数的设定水平。 但是,我遇到了一个问题,我不确定如何迭代以便生成 250 个不同的随机数以插入公式。例如我已经
我是学习 jquery 的新手,所以如果这是一个相对简单的问题,我深表歉意。我有一个 ID 为 ChartstoDisplay 的 asp.net 复选框列表。我正在尝试创建 jquery 来根据是否
我正在尝试根据在任意数量的部分中所做的选择找出生成有效案例列表的最佳方法。也许它不是真正的算法,而只是关于如何有效迭代的建议,但对我来说这似乎是一个算法问题。如果我错了,请纠正我。实现实际上是在 Ja
如果我使用 sr1 为 www.google.com 发送 DNSQR,我会收到几个 DNSRR(s) 作为回复,例如(使用 ans[DNSRR].show() 完成): ###[ DNS Resou
假设有这样一个实体类 @Entity public class User { ... public Collection followers; ... } 假设用户有成千上万的用户关注者。我想分页..
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: Nested jQuery.each() - continue/break 这是我的代码: var steps =
我刚从 F# 开始,我想遍历字典,获取键和值。 所以在 C# 中,我会说: IDictionary resultSet = test.GetResults; foreach (DictionaryEn
我知道已经有很多关于如何迭代 ifstream 的答案,但没有一个真正帮助我找到解决方案。 我的问题是:我有一个包含多行数据的txt文件。 txt 文件的第一行告诉我其余数据是如何组成的。例如这是我的
我有 12 个情态动词。我想将每个模态的 .modal__content 高度与 viewport 高度 进行比较,并且如果特定模态 .modal__content 高度 vh addClass("c
在此JSFiddle (问题代码被注释掉)第一次单击空单元格会在隐藏输入中设置一个值,并将单元格的背景颜色设置为绿色。单击第二个空表格单元格会设置另一个隐藏输入的值,并将第二个单元格的背景颜色更改为红
这是一个非常具体的问题,我似乎找不到任何特别有帮助的内容。我有一个单链表(不是一个实现的链表,这是我能找到的全部),其中节点存储一个 Student 对象。每个 Student 对象都有变量,尽管我在
有没有办法迭代 IHTMLElementCollection? 比如 var e : IHTMLLinkElement; elementCollection:IHTMLElementCollect
我正在尝试用 Java 取得高分。基本上我想要一个 HashMap 来保存 double 值(因此索引从最高的 double 值开始,这样我更容易对高分进行排序),然后第二个值将是客户端对象,如下所示
我想在宏函数中运行 while/until 循环,并限制其最大迭代次数。我找到了如何在“通常”sas 中执行此操作: data dataset; do i=1 to 10 until(con
Iterator iterator = plugin.inreview.keySet().iterator(); while (iterator.hasNext()) { Player key
晚上好我有一个简单的问题,我警告你我是序言的新手。假设有三个相同大小的列表,每个列表仅包含 1、0 或 -1。我想验证对于所有 i,在三个列表的第 i 个元素中,只有一个非零。 此代码针对固定的 i
我在 scheme 中构建了一个递归函数,它将在某些输入上重复给定函数 f, n 次。 (define (recursive-repeated f n) (cond ((zero? n) iden
我是一名优秀的程序员,十分优秀!