![](/img/trans.png)
[英]What does the C++20 standard say about usage of subojects as template non-type arguments?
[英]Dependent non-type parameter packs: what does the standard say?
我認為以下代碼格式正確:
template< typename T >
using IsSigned = std::enable_if_t< std::is_signed_v< T > >;
template< typename T, IsSigned< T >... >
T myAbs( T val );
其他人說它是不正確的,因為C ++ 17標准的§17.7(8.3):
知道哪些名稱是類型名稱允許檢查每個模板的語法。 如果以下情況,該程序格式錯誤,無需診斷:(...) 可變參數模板的每個有效特化都需要空模板參數包 ,或(...)
在我看來, IsSigned< T >...
是一個依賴模板參數,因此在模板定義時間內不能根據§17.7(8.3)進行檢查。 IsSigned< T >
對於Ts的一個子集可以是void
的,對於另一個子集或替換失敗可以是int
。 對於void
子集,確實是空模板參數包是唯一有效的特化,但int
子集可以有許多有效的特化。 這取決於實際的T
參數。
這意味着編譯器必須在模板實例化后檢查它,因為之前不知道T. 那時完整的參數列表是已知的,零可變參數。 標准說明如下(§17.6.3(7)):
當N為零時,擴展的實例化產生一個空列表。 這樣的實例化不會改變封閉結構的句法解釋
這就是為什么我認為它形成得很好。
代碼格式錯誤,無需診斷。
如果std::is_signed_v<T>
,則std::enable_if_t<std::is_signed_v<T>>
表示類型void
。 否則, std::enable_if_t<std::is_signed_v<T>>
不表示有效類型。 因此, myAbs
每個有效特化myAbs
需要一個空模板參數包。
Per [meta.rqmts] / 4 ,如果std::enable_if
是專用的,則程序具有未定義的行為。 因此,不能改變上述行為。
在我看來,
IsSigned< T >...
是一個依賴模板參數,因此在模板定義時間內不能根據§17.7(8.3)進行檢查。IsSigned< T >
對於T
s的一個子集可以是void
的,對於另一個子集或替換失敗可以是int
。 對於void
子集,確實是空模板參數包是唯一有效的特化,但int
子集可以有許多有效的特化。 這取決於實際的T
參數。
編譯器無法檢查它,就像它不能為您解決任意方程式一樣。 NDR(無需診斷)完全適用於此類情況 - 程序格式錯誤,如果編譯器實際上能夠檢測到該程序,則需要進行診斷。 NDR允許編譯器不檢查它。
當N為零時,擴展的實例化產生一個空列表。 這樣的實例化不會改變封閉結構的句法解釋。
我們所討論的規則是語義規則,而不是句法規則,因為句法規則在[gram]中。
那么NDR規則的基本原理是什么? 一般而言,它們解決了實施策略中無法重現的問題。 例如,它們可能會導致代碼在某些實現策略中出現異常,但在其他實現策略中不會導致任何問題(並且不容易)。
另外,請注意標准在程序方面與“不良形式”等術語進行對話。 因此,談論孤立的代碼片段的良好形式並不總是合理的。 在這種情況下, std::enable_if
不需要專門化,但情況可能會變得更復雜。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.