1

次のことをしようとするとします。

template</* args */>
typename std::enable_if< /*conditional*/ , /*type*/ >::type
static auto hope( /*args*/) -> decltype( /*return expr*/ )
{
}

条件付き包含/オーバーロード ( std::enable_if) と末尾の戻り型 ( auto ... -> decltype()) を組み合わせることは可能ですか?

プリプロセッサを使用したソリューションには興味がありません。私はいつものようなことができます

#define RET(t) --> decltype(t) { return t; }

それを拡張して、条件付き全体も取得します。ReturnType<A,B>::type_t代わりに、言語が戻り値の型に別の特性を使用せずにそれをサポートするかどうか、つまり関数本体で使用されるものに興味があります。

4

2 に答える 2

10

末尾の戻り値の型は、パラメーター リストと cv-/ref-qualifiers の後に指定されることを除いて、通常の戻り値の型と大差ありません。また、必ずしも必要decltypeではありません。通常のタイプでも問題ありません。

auto answer() -> int{ return 42; }

これで、あなたの質問に対する答えがわかるはずです。

template<class T>
using Apply = typename T::type; // I don't like to spell this out

template</* args */>
static auto hope( /*args*/)
    -> Apply<std::enable_if</* condition */, decltype( /*return expr*/ )>>
{
}

個人的にはdecltype、式 SFINAE を使用することを好みますが、条件を式として表現できる限り (たとえば、特定の型のオブジェクトに対して関数を呼び出すことができますか):

template<class T>
static auto hope(T const& arg)
  -> decltype(arg.foo(), void())
{
  // ...
}
于 2012-08-08T14:25:44.153 に答える
2

元の疑似コードが関数テンプレートであると想定することしかできません。そうでない場合、SFINAE は完全には機能しません。テンプレート関数の場合は、デフォルトの追加のテンプレート引数を使用し、その引数で SFINAE を使用できます。

template <typename T, typename _ = typename std::enable_if< trait<T>::value >::type >
static auto function( T arg ) -> decltype( expression ) {
   // ...
}

SFINAE の使用をtemplate句に制限し、よりクリーンな関数シグネチャを残すので、私はこれを好みます。これは、C++11 の注目すべき新機能の 1 つです。

于 2012-08-08T15:03:16.163 に答える