10

パラメトリック クラス C の場合、ポインター、const、または参照修飾子に関係なく、常に「プリミティブ」型を取得したいと考えています。

template<typename __T>
class C
{
public:
    typedef std::some_magic_remove_all<__T>::type T;
}

int main()
{
    C<some_type>::type a;
}

たとえば、次のようにsome_typeします。

  • int&
  • int**
  • int*&
  • int const &&
  • int const * const
  • 等々

私が欲しいaのは常にタイプintです。どうすれば達成できますか?

4

3 に答える 3

12

標準ライブラリをもっと使いたい場合は、次のようにします。

#include <type_traits>
template<class T, class U=
  typename std::remove_cv<
  typename std::remove_pointer<
  typename std::remove_reference<
  typename std::remove_extent<
  T
  >::type
  >::type
  >::type
  >::type
  > struct remove_all : remove_all<U> {};
template<class T> struct remove_all<T, T> { typedef T type; };

タイプが変更されなくなるまで、ものを削除します。より最近の標準では、これは次のように短縮できます。

template<class T, class U=
  std::remove_cvref_t<
  std::remove_pointer_t<
  std::remove_extent_t<
  T >>>>
  struct remove_all : remove_all<U> {};
template<class T> struct remove_all<T, T> { typedef T type; };
template<class T> using remove_all_t = typename remove_all<T>::type;
于 2013-01-25T13:45:21.870 に答える
11
template<class T> struct remove_all { typedef T type; };
template<class T> struct remove_all<T*> : remove_all<T> {};
template<class T> struct remove_all<T&> : remove_all<T> {};
template<class T> struct remove_all<T&&> : remove_all<T> {};
template<class T> struct remove_all<T const> : remove_all<T> {};
template<class T> struct remove_all<T volatile> : remove_all<T> {};
template<class T> struct remove_all<T const volatile> : remove_all<T> {};
//template<class T> struct remove_all<T[]> : remove_all<T> {};
//template<class T, int n> struct remove_all<T[n]> : remove_all<T> {};

私はもともとエクステント(配列)も削除しましたが、ヨハネスはこれが のあいまいさを引き起こすことに気づきconst char[]、質問ではそれらについて言及していません。配列も削除したい場合 (コメントで言及されているアイデアも参照してください)、次のことはそれほど複雑ではありません。

#include <type_traits>
template<class U, class T = typename std::remove_cv<U>::type>
struct remove_all { typedef T type; };
template<class U, class T> struct remove_all<U,T*> : remove_all<T> {};
template<class U, class T> struct remove_all<U,T&> : remove_all<T> {};
template<class U, class T> struct remove_all<U,T&&> : remove_all<T> {};
template<class U, class T> struct remove_all<U,T[]> : remove_all<T> {};
template<class U, class T, int n> struct remove_all<U,T[n]> : remove_all<T> {};

またはヘルパー クラスを使用するが、単一のテンプレート パラメーターを使用する場合:

#include <type_traits>
template<class T> struct remove_all_impl { typedef T type; };
template<class T> using remove_all =
  remove_all_impl<typename std::remove_cv<T>::type>;
template<class T> struct remove_all_impl<T*> : remove_all<T> {};
template<class T> struct remove_all_impl<T&> : remove_all<T> {};
template<class T> struct remove_all_impl<T&&> : remove_all<T> {};
template<class T> struct remove_all_impl<T[]> : remove_all<T> {};
template<class T, int n> struct remove_all_impl<T[n]> : remove_all<T> {};

すべての亜種がほぼ同じように見え始めるのは正常です;-)

于 2013-01-25T13:21:48.720 に答える