[英]Using non-type template argument during partial specialization
考慮以下struct
:
//Implementations provided elsewhere
struct A { A(int i, double d, std::string s); /* ... */ };
struct B { B(double d1, double d2); /* ... */ };
我有兩個轉換類,其模板簽名如下:
TupleAs< A, int, double, std::string > via1 { ... };
ArrayAs< B, double, 2 > via2 { ... };
可以預見, TupleAs
會將int
, double
和std::string
值的三元組轉換為A
類型的對象。 同樣, ArrayAs
將兩個兩個double
值對轉換為B
類型的對象。 (是的,有一些原因導致我不能直接調用A
和B
構造函數。)
改善語法
我想更改語法,以便可以執行以下操作:
TupleAs< A(int,double,std::string) > via1 { ... };
ArrayAs< B(double,2) > via2 { ... };
我認為這更能描述轉換過程。 TupleAs
模板聲明和相應的部分專業化如下所示:
template <typename T> struct TupleAs;
template <typename T, typename ... Args>
struct TupleAs<T(Args...)> { ... };
編譯錯誤
但是,如果我嘗試對ArrayAs
版本執行類似ArrayAs
:
template <typename T> struct ArrayAs;
template <typename T, typename U, unsigned N>
struct ArrayAs<T(U,N)> { ... };
嘗試實例化它時,在clang(3.6)中出現以下錯誤( ArrayAs< B(double,2)> test;
):
typeAs.cpp:14:22: error: unknown type name 'N'
struct ArrayAs<T(U,N)>{
^
typeAs.cpp:14:10: warning: class template partial specialization contains a template parameter that cannot be deduced; this partial specialization will never be used
struct ArrayAs<T(U,N)>{
^~~~~~~~~~~~~~~
typeAs.cpp:13:45: note: non-deducible template parameter 'N'
template<typename T, typename U, unsigned N>
^
gcc錯誤診斷有些不同,但是我不會在這里發布。
我承認我的模板技術應該比他們更好,並且我也承認類似的std::function<B(double,2)>
聲明顯然是胡說八道。 但是有人可以告訴我為什么不允許我嘗試實現的特定語法嗎? 我瀏覽了C ++ 14標准,找不到相關部分,並且在解釋clang診斷消息時遇到了麻煩。
當您專門研究TupleAs
:
template <typename T, typename ... Args>
struct TupleAs<T(Args...)>
您基本上是在重載函數的符號。 您正在專門研究采用Args...
並返回T
的函數 。 那是一種類型。 您可能沒有將該函數用作函數,或者甚至從未將其視為類型,但這就是它的本質。
另一方面,在這里:
template <typename T, typename U, unsigned N>
struct ArrayAs<T(U,N)> { ... };
函數不存在需要N
。 它可以是unsigned
,但不能是一個值 。 只是沒有這種合理的事情。 從您的示例來看, B(double, 2)
根本沒有道理。 充其量,您可以編寫允許以下內容的內容:
template <unsigned N> using size_ = std::integral_constant<size_t, N>;
ArrayAs< B(double,size_<2>) >
甚至:
ArrayAs< B(std::array<double, 2>) >
從現在開始,我們回到了在所有地方使用類型的地方。 個人喜好是否喜歡。
這里的關鍵是,在涉及模板元編程的所有事情時,類型是一等公民,應盡可能避免使用值。
template <typename T> struct ArrayAs;
template <typename T, typename U, std::size_t N>
struct ArrayAs<T(std::array<U,N>)> { ... };
工作原理如下:
template<class T>
struct to_array;
template<class T, size_t N>
struct to_array< T[N] > { using type = std::array<T, N>; };
template<class T>
using arr = typename to_array<T>::type;
然后:
ArrayAs< Bob( arr<int[3]> ) > some_var;
現場例子 。
可悲的是,由於函數類型中的數組如何衰減到指針,直接使用ArrayAs< Bob( int[3] ) >
不起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.