5

仮に、double型やユーザー定義型を含む数値のような型で使用できる汎用ライブラリを開発したいとします。私が今直面している問題は、次のような関数テンプレートの戻り型を作成する方法がわからないことです。

template<class T>
auto transmogrify(T x)
-> ???
{
    using std::abs;
    return abs(x)+2.0;
}

using宣言を使用すると、プリミティブ型に対してこの関数テンプレートの本体が機能します。これは、プリミティブ型に名前空間が関連付けられていないためです(したがって、ADLはありません)。しかし、ユーザー定義型の作成者が独自のabs関数を提供する場合に備えて、transmogrifyで特殊なabs関数を使用したいと思います。単純に使えない

-> decltype( abs(x)+2.0 )

std :: absがスコープ内にないため、これはたとえばdoubleに対しては機能しないためです(私が知る限り)。しかし、書く

-> decltype( std::abs(x)+2.0 )

ADLを無効にします。ただし、ADLを無効にすることはできません。また、特殊なabs関数によって返される値は、タイプTではなく、他のタイプである可能性があります。

(a)ADLを維持し、(b)特殊なabsを提供しない型のデフォルト関数(この場合はstd :: absなど)にフォールバックしながら、戻り型の問題を解決する方法に関するアイデア。

4

2 に答える 2

12

using 句を配置できる別の名前空間を使用します。using 句はその名前空間にのみ適用されるため、これにより名前空間の汚染が防止されます。誤って広めないように、一意の名前を付けることをお勧めします。

namespace transmog_detail
{
   using std::abs;

   template<class T>
   auto transmogrify(T x) -> decltype(abs(x) + 2.0)
   {
      return abs(x) + 2.0;
   }
}

// Then pull it into the current namespace, as recommended by @LucDanton.
using transmog_detail::transmogrify;

// Or if there is a reason, you can forward. 
// template<class T>
// auto transmogrify(T x)
// -> decltype(transmog_detail::transmogrify(x))
// {
//    return transmog_detail::transmogrify(x);
// }
于 2012-08-31T16:07:25.030 に答える
-6

上記の答えは良いですが、私が考えることができる最も単純な方法は、typeinfo ヘッダーを使用することです。オブジェクトの型とコンストラクターを決定するために特別に設計されました。

ここを参照してください: http://www.cplusplus.com/reference/std/typeinfo/type_info/

于 2012-08-31T16:11:19.070 に答える