変更できないクラスがいくつかあります。それぞれに、コピーコンストラクター、少なくとも1つの他のコンストラクター、および何らかの値を返す関数foo()
があります。これらの各クラスから派生でき、foo()
の戻り値の型と同じ型のデータメンバーを持つクラステンプレートを作成したいと思います(用語の一部が間違っている場合は申し訳ありません)。 。
つまり、クラステンプレートが欲しいのですが
template<typename T> class C : public T
{
footype fooresult;
};
ここで、footype
はT::foo()
の戻り値の型です。
基本クラスがすべて、たとえばデフォルトのコンストラクターを持っている場合、私は
decltype(T().foo()) fooresult;
(GCCのC++ 0x機能を使用)ただし、コピーコンストラクターを除いて、クラスには共通の特定のコンストラクターはありません。
GCCもdecltype(this->foo())
を許可していませんが、これがC++ 0x標準に追加される可能性があるようです-誰かがそれがどれほど可能性があるか知っていますか?
decltype(foo())
またはdecltype(T::foo())
に沿って何かを行うことは可能であると思いますが、それらは機能していないようです。GCCはcannot call member function 'int A::foo()' without object
の形式のエラーを出します。
もちろん、追加のテンプレートパラメータfootype
、またはタイプT
の非クラスパラメータを使用することもできますが、これを回避する方法はありますか?
それは必要ありません-decltypeはその引数を評価しないので、nullptr
を呼び出すだけでよいことを覚えておいてください。
decltype(((T*)nullptr)->foo()) footype;
別の選択肢は次のとおりです。
#include <utility>
template<typename T> class C : public T
{
decltype(std::declval<T>().foo()) footype;
};
declval
はT&&
を返します。または、fooが右辺値参照修飾子でオーバーロードされている可能性があり、fooの左辺値オーバーロードを確実に取得したい場合:
decltype(std::declval<T&>().foo()) footype;
この例では、declval
はT&
を返します。
((T*)nullptr)->
ソリューションと同様に、std::declval
はタイプT
に要件を課しません。