[英]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
(例如int
或float
)和sizeof...(N_i)+1
-many size_t
。
取決於傳遞的size_t
的數量(即sizeof...(N_i)+1
),我將對成員函數operator[](size_t)
使用不同的實現,其結果類型不同:
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.