簡體   English   中英

模板功能中的模板別名

[英]Template alias in template function

編輯:讓我們假設我有兩個(或多個)模板函數fg ,根據模板參數使用(有時)類型:

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類型,而不是我想要的類型。

如果將其設為可變參數模板,則調用者將無法定義以下所列的類型參數:

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類型,例如返回類型,可以在其中節省演員陣容。

或者,您可以使用enable_if替換static_assert

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                                                                          
}

您可以在函數旁邊聲明一個模板別名:

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;
}

一種可能的解決方案是使用operator()將模板函數轉換為template struct 例如:

#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;
}

您可以使用類似

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名稱空間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM