テンプレートの型名としてフレンドリーな名前を付けようとしています。関数内のいくつかの場所で名前を使用する必要があるからです。以下に示すようにタイプは、パラメータパック内の他のテンプレート引数の数に基づいて推測されている:テンプレートタイプ!= Deduced type
#include <cassert>
#include <functional>
#include <type_traits>
template < typename ... TArgs, typename Functor = std::function< std::conditional_t< sizeof...(TArgs) == 0, int(), int (TArgs...) > > >
void DoStuff(const Functor & func, TArgs ... args) {
if constexpr (sizeof...(TArgs) == 0)
assert(typeid(Functor).hash_code() == typeid(std::function<int()>).hash_code());
else
assert(typeid(Functor).hash_code() == typeid(std::function<int (TArgs...)>).hash_code());
}
int main(int argc, char * argv[]) {
DoStuff([]() { return 5; });
DoStuff([] (int a) { return a; });
return 0;
}
これはうまくコンパイルが、別名Functor
が実際にstd::function<>
ではないので、両方のアサーションは失敗します。一方、私は以下のように、それは完璧に動作typeid
呼び出しでFunctor
の定義を繰り返すようにコードを変更した場合:
#include <cassert>
#include <functional>
#include <type_traits>
template < typename ... TArgs, typename Functor = std::function< std::conditional_t< sizeof...(TArgs) == 0, int(), int (TArgs...) > > >
void DoStuff(const Functor & func, TArgs ... args) {
if constexpr (sizeof...(TArgs) == 0)
assert(typeid(std::function< std::conditional_t< sizeof...(TArgs) == 0, int(), int (TArgs...) > >).hash_code() == typeid(std::function<int()>).hash_code());
else
assert(typeid(std::function< std::conditional_t< sizeof...(TArgs) == 0, int(), int (TArgs...) > >).hash_code() == typeid(std::function<int (TArgs...)>).hash_code());
}
int main(int argc, char * argv[]) {
DoStuff([]() { return 5; });
DoStuff([] (int a) { return a; });
return 0;
}
なぜ(typname Functor = ...
を使用して)最初の宣言間違っては何ですか?そのエイリアスを作る別の方法はありますか? 2番目の質問に答えるには、解がconst式であれば問題ありませんが、例はtypeid
のためにconstexpr
ではないことに注意してください。
@ Jarod42これは両方のアサーションにはまだ失敗します:/ – Howard
解決しようとしている実際の問題は何ですか?なぜこのエイリアスが必要だと思いますか? – Barry
@Barry私は必要な3つの場所で定義を繰り返す必要をなくしたいと思います。私はむしろ定義を一度行い、どこでもエイリアスを使用したいと考えています。 – Howard