c++ - 違い - 変数名 命名規則




C++ 11:ポインターやイテレーターの型を取得する方法は? (2)

具体的には、 template<class Pointer> class Fooを記述していて、 pPointer型である場合に*pが持つ型の中にtypedefを宣言したいとしtypedef

C ++ 03では、私が知っている限り、これを行う唯一の方法は次のようなものです

typename std::iterator_traits<Pointer>::reference

このメソッドの欠点は、 Pointerがいくつかのカスタムイテレータ型であり、作成者がstd::iteratorを拡張することを忘れた場合、またはstd::iterator_traits特殊化を定義しなかった場合に機能しないことです。

私の同僚はC ++ 11では、

decltype(*Pointer())

Pointerがデフォルトで構成可能でない場合、これは機能しませんので、

decltype(**(Pointer*)0)

私はこれを試してみましたが、うまくいきましたが、ヌルポインタの逆参照を伴い、標準に準拠していない可能性があるため、少し見えると思っていました。

私たちはもっとうまくできますか?


C ++ 03では、指定された型からすべてのポインタを削除する単純な構文を書くことができます:

template<typename T>
struct ActualType { typedef T type; };
template<typename T>
struct ActualType<T*> { typedef typename ActualType<T>::type type; };

int*またはint**を渡すと、最後にActualType<T>::typeint沸騰します。

ここにdemoます。


あなたはヌルポインタの逆参照について慎重であることは間違いありませんが、実際はここでOKです! decltypeはそのオペランドを評価しないので、内部でヌルポインタの逆参照は完全に有効です。

しかし、適切な解決策はstd::declval 、C ++ 11の<utility>中に導入されてい<utility>

decltype(*std::declval<Pointer>())




c++11