右辺値/左辺値/コンテナ/コンテナ以外を引数としてなんでも渡し標準出力する関数を作成しています。
コンテナ以外の値(int, doubleなど)を想定して作成した関数のオーバーロードを追加すると失敗してしまいます。
なぜ特定に失敗してしまうのでしょうか。またどのように修正すべきかご教示いただけると助かります。
cpp
1#include <bits/stdc++.h> 2 3template<typename T, typename = void> 4struct is_container : std::false_type {}; 5 6template<typename... Ts> 7struct is_container_helper {}; 8 9template<typename T> 10struct is_container< 11 T, 12 std::conditional_t< 13 false, 14 is_container_helper< 15 typename T::value_type, 16 typename T::size_type, 17 typename T::iterator, 18 typename T::const_iterator, 19 decltype(std::declval<T>().size()), 20 decltype(std::declval<T>().begin()), 21 decltype(std::declval<T>().end()), 22 decltype(std::declval<T>().cbegin()), 23 decltype(std::declval<T>().cend()) 24 >, 25 void 26 > 27> : public std::true_type {}; 28 29template <typename T> 30constexpr auto is_container_v = is_container<T>::value; 31 32auto f(){}; 33 34// lvalueコンテナ用 35template<typename Head, typename... Tail, std::enable_if_t<is_container_v<Head>, std::nullptr_t> = nullptr> 36auto f(Head& head, Tail&&... tail) { 37 for (auto& h : head) { 38 if (&h != &head.back()) std::cout << h << " "; 39 else std::cout << h << std::endl; 40 } 41 f(std::forward<Tail>(tail)...); 42} 43 44// rvalueコンテナ用 45template<typename Head, typename... Tail, std::enable_if_t<is_container_v<Head>, std::nullptr_t> = nullptr> 46auto f(Head&& head, Tail&&... tail) { 47 for (auto&& h : head) { 48 if (&h != &head.back()) std::cout << h << " "; 49 else std::cout << h << std::endl; 50 } 51 f(std::forward<Tail>(tail)...); 52} 53 54// コンテナ以外の値出力(のつもりだったができない) 55// コメントを外すとSFINAE失敗する 56/* 57template <typename Head, typename... Tail, std::enable_if_t<!is_container_v<Head>, std::nullptr_t> = nullptr> 58auto f(Head&& head, Tail&&... tail) { 59 if (sizeof...(Tail)) std::cout << head << " "; 60 else std::cout << head << std::endl; 61 f(std::forward<Tail>(tail)...); 62} 63*/ 64 65int main() { 66 // 左辺値array -> OK 67 std::array<std::string, 3> arr{"first", "second", "third"}; 68 f(arr); 69 70 // 左辺値vector複数 -> OK 71 std::vector<int> vec{11, 13, 17, 19, 22}; 72 f(vec, vec); 73 74 // 右辺値vector -> OK 75 f(std::vector<int>{1, 2, 3}); 76 77 // 右辺値vector複数 -> OK 78 f(std::vector<int>{11, 11, 11}, std::vector<int>{22, 22, 22}); 79 80 // 左辺値/右辺値/コンテナ/その他関係なく出力したい 81 //f(vec, std::vector<int>{99, 99, 99}, 123); 82}
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2020/03/24 10:36