2016-11-04 8 views
1

私はC++オーバーロード関数

void f(int); 
void f(std::string); 

そしてfと同じプロトタイプを持つ2つのオーバーロード関数gのような2つのオーバーロードされた機能を持っていますが、fへの単純なラッパーである、ので、その実装はまったく同じです。

void g(int n) { f(n);} 
void g(std::string n) { f(n); } 

gの実装を2回書くことを避ける方法はありますか?私は、これは

template<typename T> g(T n) { f(n);} 

のようなテンプレートを経由してgを宣言することによって行うことができます知っているが、私は私が正しい方法だ何さまよう

g<int>(2); 
g<std::string>("42"); 

に似関数呼び出しのタイプを入力する必要がありますgの実装を2回書くのを避けるために、各関数呼び出しで型名を明示的に書く必要はありませんか?

+1

"しかし、関数に型を入力する必要があります"、いいえ、あなたは必要ありません。テンプレート引数の控除はそれを行います。 –

答えて

4

“しかし、私は関数”の型を入力する必要があります。いいえ、あなたは必要ありません。 テンプレート引数の控除あなたのためにそれを行います。したがって、関数テンプレートは実用的な解決策です。それはvoid戻り値の型を必要とすることを除いて

あなたが書いた1、

template<typename T> g(T n) { f(n);} 

は大丈夫です。

template< class Arg > 
void g(Arg&& arg) { f(std::forward<Arg>(arg)); } 
ここ

&&右辺値参照が、いわゆるユニバーサル参照を表すものではありませんそれはテンプレート引数に適用されているため、次のように


あなたは移動-最適化をサポートすることができますそれはすでに参照になる可能性があります。

ほとんどの場合、std::forwardは実際の引数の種類を正確に再現できるということです。完全転送と呼ばれています。

3

gの実装を2回書くことを避ける方法はありますか?

はい、あります。私はこれを知っている

あり

あなたが行くようにテンプレート経由グラムを宣言することによって行うことができます。

が、その後、私は、関数呼び出し

いいえ、そうでないタイプを入力する必要があります。コンパイラにタイプを推論させることができます:

g(2); 
g("42"); 
関連する問題