2016-12-21 5 views
5

私はコンセプトで遊んでいます。ここで私はメソッドのシグネチャに基づいてコンセプトを作成しようとしている最低限の例です:概念:引数のあるメソッドのシグネチャをチェックする

私の驚きの書き込み { a.bar(int) } -> int
template<typename T> 
concept bool myConcept() { 
    return requires(T a, int i) { 
     { a.foo() } -> int; 
     { a.bar(i) } -> int; 
    }; 
} 

struct Object { 
    int foo() {return 0;} 
    int bar(int) {return 0;} 
}; 

static_assert(myConcept<Object>(), "Object does not adhere to myConcept"); 

は動作しませんでしたので、私はrequires表現への追加の引数を追加することに頼っ。これはちょっと変わったようで、同じことをする方法があるのだろうかと思っていました。働いていた別のものは{ a.bar((int)0) } -> intのようなものを使っていましたが、私はこれを悪化させています。

答えて

6

コンセプトチェック式で、a.bar(int)は1ではありません。

{ a.foo(int) } -> int 

を書くことによって、あなたは上記の式はintを入力したことを確認するために、コンパイラをお願いします。どちらが理にかなっていない。

有効な代替手段が見つかりました。タイプの実際の値は重要ではありません

template<typename T> 
concept bool myConcept() { 
    return requires(T a) { 
     { a.foo() } -> int; 
     { a.bar(0) } -> int; 
    }; 
} 

struct Object { 
    int foo() {return 0;} 
    int bar(int) {return 0;} 
}; 

static_assert(myConcept<Object>(), "Object does not adhere to myConcept"); 
3

として、私は、引数としてint{}を使用することをお勧めしたい:a.bar(x)のタイプはx 'の値に依存しないため、他の一つは、あるかもしれません。これは、IMO、幾分良好引数の目的を文書化:

{ a.bar(int{}) } -> int; 

明らかにこれにはデフォルトコンストラクタがないいるタイプでは動作しません。テンプレートでは、1は、周りの同様の問題が、ここではGCCエラー仕事にstd::declvalを使用します。

error: static assertion failed: declval() must not be used! 

をしかし、同等の(ただし未実装)の書き込みから私たちを止めるものは何もありません概念で使用される機能を、このように:

#include <type_traits> 

template <class T> 
typename std::add_rvalue_reference<T>::type makeval(); 

template<typename T> 
concept bool myConcept() { 
    return requires(T a, int i) { 
     { a.foo() } -> int; 
     { a.bar(makeval<int>()) } -> int; 
    }; 
} 

struct Object { 
    int foo() {return 0;} 
    int bar(int) {return 0;} 
}; 

static_assert(myConcept<Object>(), "Object does not adhere to myConcept"); 
+0

私はあなたがメイクのようです()と私は標準でそれを見たいと思います。 – YSC