我已经在这个几个月里开始关闭了我的大脑。我已经定义了一组概念,它们粗略地描述了容器和谓词。Concepts-Lite迭代器比较比较
通常,我使用老式的for
循环遍历容器并将参数迭代器的等式与迭代器的end(container)
进行比较。我想不出就是为什么当给予Container<T>
这样T
不具有相等比较这不会编译(T::operator==(T other)
)
这些概念是不完整,并且仅仅是为了学习目的,有毫无疑问,其他方式可以完成我正在做的事情。
问题的代码是在“queryalgorithms.h”定义这短短的功能:
#pragma once
#include <algorithm>
#include "concepts.h"
template<typename C, typename P, typename V = typename C::value_type, typename I = typename C::iterator>
I last(C & collection, I iterator, P predicate) requires Container<C> && Predicate<P, V> && Incrementable<I> {
I out;
for (iterator; iterator != end(collection); iterator++) {
}
return out;
}
其失败的测试代码是在这里:
#include <iostream>
#include <vector>
#include <algorithm>
#include <forward_list>
#include "queryalgorithms.h"
using namespace std;
class MyClass {
public:
int value;
MyClass(int v): value(v) {};
};
template <typename T>
void Test() {
auto collection = T();
for (auto i = 0; i < 10; i++)
last(collection, begin(collection), [] (auto x) { return true; });
}
int main(int argc, char * argv[]) {
Test<vector<MyClass>>();
return 0;
}
不知道这是多大的帮助,但为了完整,concepts.h文件是here。这是很多,我不觉得它增加了很多价值,所以我把它放在pastebin上。
如上所述,小示例仅针对定义了相等比较器的类型进行编译(例如,Test<vector<int>>()
将正常工作)。而从G ++编译器错误如下:
/usr/include/c++/6.3.1/bits/stl_algobase.h:800:22: error: no match
for ‘operator==’ (operand types are ‘const MyClass’ and ‘const MyClass’)
if (!(*__first1 == *__first2))
所以我的问题是,为什么编译器推断类型的iterator != end(collection)
是值类型V
而不是迭代器类型I
?
编辑:我使用g++ -fconcepts --std=c++17 -o test test.cc
不可否认,我搞乱了'容器'的定义与你引用的标准有关,所以非常感谢。我对容器的定义(注意它是一个自定义定义)要求“容器”本身是“EqualityComparable”而不是“Container :: value_type”。调整到'Container'的'EqualityComparable'的正确定义会导致您在答案中指定的错误更短。但是,我不认为这回答了如前所述的原始问题 –
Howard
更改此子句:“上一个要求子句实例化向量的赋值运算符...”到“...实例化向量的相等运算符..”,我将接受这个答案。这个问题是由于我把'Container'的'EqualityComparable'的定义搞乱了,而不是它的值类型。谢谢 – Howard
Woops,那里有巨大的思考。 – Casey