【发布时间】:2017-05-12 19:42:52
【问题描述】:
几个月来,我一直在为此绞尽脑汁。我已经定义了一组松散地描述容器和谓词的概念。
一般来说,我使用老式的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进行编译
【问题讨论】:
标签: c++ c++11 c++-concepts