1

編集: 2 つ (またはそれ以上) のテンプレート関数がfありg、そのテンプレート パラメーターに応じて (場合によっては) 型を使用するとします。

template<typename T>
some_ugly_and_large_or_deep_template_struct_1<T>::type 
f(const some_ugly_and_large_or_deep_template_struct_1<T>::type&,
  const some_ugly_and_large_or_deeptemplate_struct_1<T>::type&)
{
   // body, that uses perhaps more times my
   // "some_ugly_and_large_or_deep_template_struct_1<T>"
}

template<typename T>
some_ugly_and_large_or_deep_template_struct_2<T>::type 
g(const some_ugly_and_large_or_deep_template_struct_2<T>::type&,
  const some_ugly_and_large_or_deeptemplate_struct_2<T>::type&)
{
   // body, that uses perhaps more times my
   // "some_ugly_and_large_or_deep_template_struct_2<T>"
}

たとえば、新しい C++11 のツールのいずれかを使用して、この「型」定義を単純化するにはどうすればよいですか? 私は次のようなことだけを考えています:

template<typename T,
         typename aux = some_ugly_and_large_or_deep_template_struct_1<T>::type>
aux f(const aux&, const aux&)
{
  // body, that uses perhaps more times my
  // "aux" type
}

template<typename T,
         typename aux = some_ugly_and_large_or_deep_template_struct_2<T>::type>
aux g(const aux&, const aux&)
{
  // body, that uses perhaps more times my
  // "aux" type
}

このアプローチで私が目にする問題は、ユーザーが自分のauxタイプではなく、自分のタイプを提供できることです。

4

4 に答える 4

5

可変個引数テンプレートにすると、呼び出し元は、次にリストされている型パラメーターを定義できなくなります。

template<typename T,
         typename..., // firewall, absorbs all supplied arguments
         typename aux = some_ugly_and_large_or_deep_template_struct_1<T>::type>
aux f(const aux&, const aux&)
{
  // body, that uses perhaps more times my
  // "aux" type
}

必要に応じて、あまりにも多くのテンプレート引数で誤って呼び出すのを防ぐためfに、static_assert を追加できます。

template<typename T,
         typename... F,
         typename aux = some_ugly_and_large_or_deep_template_struct_1<T>::type>
aux f(const aux&, const aux&)
{
  static_assert(sizeof...(F)==0, "Too many template arguments");
  // body, that uses perhaps more times my
  // "aux" type
}

通常、ユーザーが のような型を定義できるようauxにすることで対応できます。たとえば、これによりキャストを節約できる戻り値の型です。

static_assertまたは、を次のように置き換えることができますenable_if

template<typename T,
         typename... F, typename = typename std::enable_if<sizeof...(F)==0>::type,
         typename aux = some_ugly_and_large_or_deep_template_struct<T>::type,>
aux f(const aux&, const aux&)
{
  // body, that uses perhaps more times my                                               
  // "aux" type                                                                          
}
于 2013-02-02T00:15:07.253 に答える
2

関数と一緒にテンプレート エイリアスを宣言できます。

template<typename T> using f_parameter
  = typename some_ugly_and_large_or_deep_template_struct<T>::type;

template<typename T>
f_parameter<T> f(const f_parameter<T>&, const f_parameter<T>&)
{
   f_parameter<T> param;
}
于 2013-02-01T14:59:04.577 に答える
1

次のようなものを使用できます

namespace f_aux {
   template <typename T> using type = 
            typename some_ugly_and_large_or_deep_template_struct<T>::type;
}

template <typename T>
f_aux::type<T> f(const f_aux::type<T>& , const f_aux::type<T>&);

f の宣言が適切な名前空間またはクラスにある場合、追加のf_aux名前空間は必要ない場合があります。

于 2013-02-01T15:02:56.593 に答える
1

考えられる解決策は、テンプレート関数を を使用して に変換することtemplate structですoperator()。例えば:

#include <iostream>
#include <string>

template <typename T>
struct some_ugly_and_large_or_deep_template_struct
{
    typedef T type;
};

template <typename T>
struct f
{
    typedef typename some_ugly_and_large_or_deep_template_struct<T>::type aux;

    aux operator()(const aux& a1, const aux& a2)
    {
        return a1 + a2;
    }
};

int main()
{
    std::cout << f<int>()(4, 4) << "\n";
    std::cout << f<std::string>()("hello ", "world") << "\n";
    return 0;
}
于 2013-02-01T14:52:30.390 に答える