4

部分関数テンプレートが混乱して不要であると見なされ、C ++標準で許可されていない理由は、今では理解できたと思います。ただし、部分的な特殊化なしで次の関数を言い換えるのに役立つことを感謝します。FWIW、関数は非特殊クラスのメンバーです:

template <typename IMPL, typename RET>
RET call (functor <IMPL> func, 
          IMPL * impl)
{ 
  return func.call (impl);
}

template <typename IMPL>
void call <IMPL, void_t> (functor <IMPL> func, 
                          IMPL * impl) 
{ 
  func.call (impl);
}

ここでの問題は、関数の戻り型をオーバーロードできないことです。また、私が専門にしたい型名は関数パラメーターとして使用されていません-オーバーロードが役に立たないもう1つの理由です。はい、オーバーロードを強制するためにダミーパラメータを導入することはできますが、それは醜いですね。

最後に、なぜ一体がC ++の型を「無効」にしないのですか?それは物事をはるかに一貫性のあるものにするでしょう...しかし、私はおそらく全体像を見逃しています...

4

5 に答える 5

7

まず、voidを返す関数がある場合、それreturnはvoid式に完全に正当であると信じています。たとえば、voidを返す別の関数の呼び出しなど、 C ++では完全な型でvoid あり、次のように渡すことができます。好きなだけテンプレート。

于 2011-08-11T21:06:56.380 に答える
2

functorテンプレートクラスにすでにRETのtypedefがある場合は、代わりにこれを行うことができます。

template <typename IMPL>
typename functor<IMPL>::RET call (functor <IMPL> func, 
          IMPL * impl)
{ 
  return func.call (impl);
}

過負荷を気にしないでください。また、使用しているコンパイラは何ですか?voidすべての標準準拠コンパイラでは、関数から関数の結果を返すことができますvoid

于 2011-08-11T21:05:36.037 に答える
2

関数の部分的な特殊化の一般的な解決策は、関数と同じ引数を持つ単一のメソッドで、同じテンプレート引数を持つヘルパークラステンプレートを使用することです。テンプレートクラスは、部分的に特殊化できます。

voidただし、あなたの場合は、他の回答で指摘されているように、返品タイプとして使用できるはずだと思います。

于 2011-08-11T21:12:32.560 に答える
2

初め、

template <typename IMPL, typename RET>
RET call (functor <IMPL> func, 
          IMPL * impl)
{ 
  return func.call (impl);
}

本当にする必要があります

template <typename RET, typename IMPL>
RET call (functor <IMPL> func, 
          IMPL * impl)
{ 
  return func.call (impl);
}

(私は反転RETIMPL、テンプレート引数リストにあります)次のような関数を呼び出すことができます

call<int>(f, impl);

入力する代わりに

call<impl_type, int>(f, impl);

確かに、コンパイラは推測できないRETので、自分で提供する必要があります。

void次に、式を返すことができるので、のためにオーバーロードする必要はありませんvoid。必要に応じて、オーバーロードを追加できます。

template <typename IMPL>
void call(functor<IMPL> func, IMPL* impl)

call(f, impl)このオーバーロードを呼び出すときに使用します。

C ++ 0xにアクセスできる場合は、の使用を検討してdecltypeください。

于 2011-08-11T21:21:39.090 に答える
1

これは、関数のオーバーロードを使用して行うことができます。

template <typename IMPL, typename RET>
RET call (functor <IMPL> func, 
          IMPL * impl)
{ 
  return func.call (impl);
}

template <typename IMPL>
void call (functor <void_t> func, void_t * impl) 
{ 
  func.call (impl);
}

また、voidC++のタイプです。どうしてそうではないと思いますか?

于 2011-08-11T21:06:18.050 に答える