2017-05-12 16 views
0

私は数ヶ月間この問題を解消しています。私は、コンテナと述語を緩やかに記述する一連の概念を定義しました。Concepts-Liteイテレーターの比較で値が比較されます

一般的に、私は古い形式のforループを使ってコンテナをループし、パラメータイテレータの等価性をend(container)イテレータと比較しています。これらの概念があり、決して完全ではありませんで、学習目的のために、単純ですTは等値比較子を持たないようにContainer<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 ++からのコンパイルエラーは次のとおりです。だから私の質問は、なぜコンパイラは、値型Vではなく、イテレータ型Iするiterator != end(collection)の種類を推定されている

/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)) 

編集:私はg++ -fconcepts --std=c++17 -o test test.cc

答えて

1

Container<T>は左辺値aとタイプTbためa == b必要とEqualityComparable<T>を必要とする使用してコンパイルしています。 C++標準では、コンテナのa == bは値の型がEqualityComparableN4659 [container.requirements.general] Table 83)であることが必要です。 last私はアルゴリズムがstl_algobase.hの行800に定義されている推測する最も可能性の高いstd::equalの面で実装されているvector==演算子を、インスタンス上でContainer<vector<MyClass>>をチェック は句が必要です。

MyClassEqualityComparableではないため、vector<MyClass>Containerをモデル化していません。特に、標準ではvector(または任意のコンテナ)のoperator==を制約する必要がないため、last SFINAEの代わりに制約をチェックするとハードエラーが発生し、過負荷解決からそれ自体が削除されます。

+0

あなたが引用した標準に関して、私はコンテナの定義を使いこなしました。ありがとうございます。コンテナ(私はカスタム定義です)の定義では、 'Container '自体が 'Container :: value_type'ではなく' EqualityComparable'である必要がありました。 'Container'の' EqualityComparable'の正しい定義に調整すると、あなたの答えに指定したように、ずっと短いエラーが残されます。しかし、私はこれが元の質問に答えたとは思わない – Howard

+0

この節を変更してください: "最後にrequire節がベクトルの代入演算子をインスタンス化します..."を "...ベクトルの等価演算子をインスタンス化します"この答え。この問題は、その値の型ではなく、 'Container'に対する' EqualityComparable'の定義が誤っているために起こりました。ありがとう – Howard

+0

巨大なthinkoがあります。 – Casey