24

(C++98 でこれを行う一般的な方法はないと思うので、この質問を C++11 に制限します)。

複雑な (シグネチャの観点から)テンプレート関数やオーバーロードされた関数のセットがあり、これらの関数をまったく同じ方法で使用したいが、別の名前 (つまり、エイリアス) を使用したいとします。

例えば:

template<class A, class B, class C> 
D fun(A a, B& b, C&& c){ ... }

template<class E, class F> 
G fun(H<E> he, F& f){ ... }

... many other versions of fun

ここで、これらの関数の名前を一度に変更(より正確にはalias、またはforward ) したいとします (つまり、同じ関数を書き換えずに別の名前を使用できるようにする)。そのため、コードの他の部分では、上記のコードを変更せずに別の名前で使用できます。

これは(エイリアス/転送)に名前を変更する正しい方法ですか?fungun

template<typename... Args> 
inline auto gun(Args&&... args)->decltype(fun(std::forward<Args>(args)...)){
    return fun(std::forward<Args>(args)...);
}
  • それは本当に一般的なものですか?
  • これは最も簡単な方法ですか?
  • これは最適な方法ですか?(例: インライン化可能、不要なコピーなし)
  • 元の関数にいくつかの SFINAE 機能があった場合はどうなるでしょうか? (例template<class A, class B, class C, class = std::enable_if< ... >::type>)、decltypeすべての場合に SFINAE を転送しますか?
  • 元の関数が参照を返すとどうなるでしょうか? decltype は参照型を削除しようとしていませんか? (例double& fun(double& x){return x;})。
  • メンバー関数についても同じことが言えますか?

明確化:インスタンスのアドレスが異なるため、 が正確gunになることは決してありませんが、私が探しているのは、汎用コーディングの観点からの名前変更です。 fun

コメント: ほとんどすべての名前変更/転送、名前空間、型 ( typedef) およびテンプレート型using typedefが可能であるのに、関数 (またはメンバー関数) ができないことは奇妙です。


編集:完全を期すために、これがそれを行う方法のように思われるため、ここで関数エイリアスを定義するマクロを追加しました:

#define ALIAS_FUNCTION(OriginalnamE, AliasnamE) \
template <typename... Args> \
inline auto AliasnamE(Args&&... args) -> decltype(OriginalnamE(std::forward<Args>(args)...)) { \
  return OriginalnamE(std::forward<Args>(args)...); \
}

そして、次のように使用します。

namespace NS1{namepsace NS2{
  ALIAS_FUNCTION(NSA::fun, gun); // second argument (target name can't have namespace)
}}

EDIT2:エイリアスにも例外ポリシーを組み込むことができると思います:

#define ALIAS_FUNCTION(OriginalnamE, AliasnamE) \
template <typename... Args> \
inline auto AliasnamE(Args&&... args) \
  noexcept(OriginalnamE(std::forward<Args>(args)...)) \
->decltype(OriginalnamE(std::forward<Args>(args)...)){\
    return OriginalnamE(std::forward<Args>(args)...);}

しかし、まだテストしていません。 3 回入力する必要があります

4

1 に答える 1

13

それは本当に一般的なものですか?

はい。

これは最も簡単な方法ですか?

はい(悲しいことに)。

これは最適な方法ですか?(例: インライン化可能、不要なコピーなし)

はい。

元の関数にいくつかの SFINAE 機能があった場合はどうなるでしょうか? (例template<class A, class B, class C, class = std::enable_if< ... >::type>) decltype はすべての場合に SFINAE を転送しますか?

はい、内部の式でdecltypeエラーが発生した場合 (つまり、funおそらく SFINAE on が原因で存在しない場合fun)、これにより SFINAE もトリガーgunされ、オーバーロード セットから削除されます。

元の関数が参照を返すとどうなるでしょうか? decltype は参照型を削除しようとしていませんか? (例double& fun(double& x){return x;})。

いいえ、なぜですか?

メンバー関数についても同じことが言えますが、これは私が推測するクラスを変更する必要があります。

これは質問ではありません。メンバー関数について何が言えますか? 上記のすべてが等しく適用されます。

于 2012-12-04T15:27:55.587 に答える