簡體   English   中英

成員函數實現取決於模板參數

[英]member function implementation depending on template parameter

我有以下問題:

template< typename T, size_t N, size_t... N_i >
class A
{  
  public:

    // ...

    // first implementation
    template< size_t M = sizeof...(N_i)+1, typename std::enable_if< M!=1, size_t >::type = 0 >
    A<T, N_i...> operator[]( size_t i )
    {
      A< T, N_i... > res{ ... };

      return res;
    }

    // second implementation
    template< size_t M = sizeof...(N_i)+1, typename std::enable_if< M==1, size_t >::type = 0 >
    T operator[]( size_t i )
    {
      return ... ;
    }
};

正如您在上面所看到的,我嘗試實現一個類A ,它希望作為模板參數的類型為T (例如intfloat )和sizeof...(N_i)+1 -many size_t

取決於傳遞的size_t的數量(即sizeof...(N_i)+1 ),我將對成員函數operator[](size_t)使用不同的實現,其結果類型不同:

  • case sizeof...(N_i)+1 > 1一個實現,返回類型為A < T, N_i... > (在代碼中稱為“第一個實現”)
  • 一個用於sizeof...(N_i)+1 == 1 ,返回類型為T (在代碼中稱為“第二個實現”)。

不幸的是,我不知道如何實現這一點 - 上面的解決方案不起作用。 有人有想法嗎?

提前謝謝了。

如果你修改

A< T, N_i... > res{ ... };

A< T, N_i... > res{ };

return ... ;

return T{} ;

還不夠嗎?

---編輯---

不:正如Jarod42指出的那樣(謝謝!),還不夠。

所以我提出了以下解決方案,基於類模板特化和std::conditional來避免使用SFINAE

#include <iostream>
#include <type_traits>

template< typename, size_t...>
class A;

template< typename T, size_t N, size_t... N_i >
class A<T, N, N_i...>
 {  
   public:
      template <typename Next = typename std::conditional<sizeof...(N_i),
                                           A<T, N_i...>, T>::type>
      Next operator[] (size_t i)
       { return Next{}; }
 };

int main(int argc, char* argv[]) 
 {
   A<int, 2, 4> a;

   std::cout << a[1][2] << std::endl;

   return 0;
 }

如果你不想專注A ,你可以添加的子結構A做骯臟的工作。

#include <iostream>
#include <type_traits>

template< typename T, size_t N, size_t... N_i >
class A
 {  
   template <typename U, size_t ... O_i>
      struct Next
       { using type = A<U, O_i...>; };

   template <typename U>
      struct Next<U>
       { using type = U; };

   public:
      using next_t = typename Next<T, N_i...>::type;

      next_t operator[] (size_t i)
       { return next_t{}; }
 };

int main(int argc, char* argv[]) 
 {
   A<int, 2, 4> a;

   std::cout << a[1][2] << std::endl;

   return 0;
 }

對於空N_i A<T, N_i...>無效。 作為解決方法,您可以使用間接:

template <typename, std::size_t ...>
struct PopFrontA
{
    using type = void; // Dummy type for A<T, N>
};

template< typename T, std::size_t N, std::size_t... N_i > class A;

template <typename T, std::size_t N, std::size_t N2, std::size_t ... Ns>
struct PopFrontA<T, N, N2, Ns...>
{
    using type = A<T, N2, Ns...>;
};

template <typename T, std::size_t ... Ns>
using PopFrontA_t = typename PopFrontA<T, Ns...>::type;

然后

// first implementation
template< size_t M = sizeof...(N_i)+1, typename std::enable_if< M!=1, size_t >::type = 0 >
PopFrontA_t<T, N, N_i...>
operator[]( size_t i )
{
  A< T, N_i... > res{ /*...*/ };

  return res;
}

演示

暫無
暫無

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

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