質問
print()
を持つ場合はprint1で、begin()
, end()
を持つ場合は配列形式で表示するprint2で、
そうでない場合はprint3関数で呼び出したいです。
「分かっていること」に書いている方法であれば、2つであればまだかけそうですが、4つ5つを想定すると厳しそうです。
cpp
1#include <bits/stdc++.h> 2using namespace std; 3 4template <typename P> 5ostream& print(ostream& o, const P& p) { // print1 6 p.print(); 7 return o; 8} 9 10template <typename V> 11ostream& print(ostream& o, const V& v) { // print2 12 o << '['; 13 for (const auto& e : v) { 14 o << ' '; 15 print(e); 16 o << ' '; 17 } 18 return o << ']'; 19} 20 21template <typename T> 22ostream& print(ostream& o, const T& t) { // print3 23 return o << t; 24} 25 26int main() { 27 vector<int> v = {1, 2, 3}; 28 int i = 50; 29 print(v); // print2 30 print(i); // print3 31 return 0; 32}
環境はC++14を使っていますが、より綺麗に書けるのであればC++20も検討したいです(conceptは避けたいです)。
分かっていること
上記のコードはコンパイルエラーになるのですが、print2を「begin()を含む場合にenable」、print3を「begin()を含まない場合にenable」とすれば、sfinaeによって解決できそうです。
しかし、この方法では以下の問題があり、あまり良いデザインでは無さそうです。
- 「begin()を含むかどうか」のメタクラスの設計が必要
- 完全に実装すると「printを含む場合」かつ「beginを含まない場合」となるため、記述量が増える
回答1件
あなたの回答
tips
プレビュー