質問内容
c++20のrequires式の定義にまつわる質問です。
下記コード1はidentification関数の引数に
入力した値の型が構造体Hogeの場合
標準出力に"Hogeです"と表示し、
Hogeでない場合は"Hogeではない"
と表示するプログラムです。
その中のidentification関数では引数で使用されている
コンセプトのHogeConceptでは
構造体Hogeのメンバであるfuga関数(引数、戻り値ともに整数全般)があるかどうかで
引数(HogeConcept auto const&)がHogeかどうかを判別し
型の入力制限を行います。
しかしコード1ではHogeConceptの定義部分が長くなってしまいます。
整数型全般を表せる型を書けることができたとしたら
下記コード2のように1行で済ませることができそうなのですが
そのような型を書くことができるのでしょうか。
ちなみに私はコード3のように書けば良いのではないかと考え
書いてみましたが
error: 'auto' not allowed in template argument
(エラー:「auto」はテンプレート引数では許可されていません)
とコンパイルエラーを吐いてしまい動きませんでした。
御回答どうか宜しくお願い致します。
注意:
identification関数を下記コード4のように書けばHogeConceptを
書かずに済むが、本質問ではこのような方法は用いないものとする。
コード1
c++
1#include <iostream> 2#include <concepts> 3#include <utility> 4 5template<typename Type> 6concept HogeConcept = requires(Type t1){// template引数やautoの型をHogeと推論させるためのコンセプト 7 {t1.fuga(short())} -> std::integral<>; 8 {t1.fuga(std::declval<unsigned short>())} -> std::integral<>; 9 10 {t1.fuga(int())} -> std::integral<>; 11 {t1.fuga(std::declval<unsigned int>())} -> std::integral<>; 12 13 {t1.fuga(long())} -> std::integral<>; 14 {t1.fuga(std::declval<unsigned long>())} -> std::integral<>; 15 16 {t1.fuga(std::declval<long long>())} -> std::integral<>; 17 {t1.fuga(std::declval<unsigned long long>())} -> std::integral<>; 18 19}; 20 21struct Hoge{ 22 template<std::integral Type> 23 Type fuga(const Type arg){return arg;} 24}; 25 26void identification(HogeConcept auto const&){// 引数がHogeのオブジェクトの場合実行 27 std::cout << "Hogeです" << std::endl; 28} 29 30void identification(...){// 引数がHogeのオブジェクト以外の場合実行 31 std::cout << "Hogeではない" << std::endl; 32} 33 34int main(){ 35 auto hoge = Hoge(); 36 37 identification(hoge); 38 identification(int()); 39 40 return 0; 41}
実行結果
terminal
1Hogeです 2Hogeではない
コード2
c++
1template<typename Type> 2concept HogeConcept = requires(Type t1){ 3 {t1.fuga([整数型全般を表せる型])} -> std::integral<>; 4};
コード3
c++
1template<typename Type> 2concept HogeConcept = requires(Type t1){ 3 {t1.fuga(std::declval<std::integral auto>())} -> std::integral<>; 4};
コード4
c++
1void identification(std::same_as<Hoge> auto const&){ 2 std::cout << "Hogeです" << std::endl; 3}
開発環境の備考
種類 | 名前 | バージョン | 備考 |
---|---|---|---|
os | Linux Mint | 20 | - |
コンパイラ | clang++ | 10 | 本文中のコードをコンパイルする時オプションに-std=c++2aを指定 |
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2020/11/03 21:55