size()メンバ関数を保持するかどうか調べるメタ関数has_sizeを作ります。
C++
1namespace 2{ 3 template <typename T> 4 struct has_size_helper 5 { 6 private: 7 template <typename U> static auto test(int) 8 -> decltype(std::declval<U&>().size(), std::true_type()); 9 template <typename U> static auto test(...) 10 -> decltype(std::false_type()); 11 public: 12 using type = decltype(test<T>(0)); 13 }; 14} 15template <typename T> struct has_size 16 : has_size_helper<std::remove_reference_t<T>>::type {}; 17template <typename T> constexpr bool has_size_v = has_size<T>::value;
これを使って型判定を行っていました。
C++
1// size()メンバ関数を持っているオブジェクトにだけ呼び出し可能。 2template <typename T> 3bool f(T&&, std::enable_if_t<has_size_v<T>>* = nullptr) { ... }
上記を前提として...
こんなクラスに出会いました。
C++
1template <typename T> 2struct Holder 3{ 4 T entity_; 5 operator T const&() const { return entity_; } 6};
HolderのTにsize()メンバ関数を持つクラスを指定された状態では、f(Holder<T>())は当然SFINAEで候補から落とされてしまいます。
しかしf()内の実装は、Holder<T>をTにキャストさえできれば問題なく動作するのです。
そしてTやHolderは後から追加される任意の型でも問題ないようにしたいと思います。なので各型に対してオーバーロードしたり特殊化したりはしなくてすむようにしたいです。
上記の条件で、f()がHolder<T>を受け付けられるようにできるものでしょうか?
キャスト先の型を直接指定できない時点で、私の知識では無理なのですが...。
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。