(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 ) したいとします (つまり、同じ関数を書き換えずに別の名前を使用できるようにする)。そのため、コードの他の部分では、上記のコードを変更せずに別の名前で使用できます。
これは(エイリアス/転送)に名前を変更する正しい方法ですか?fun
gun
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 回入力する必要があります。