[英]C++20 designated initializers with templated types
指定的初始值設定項(C ++ 20)應該如何與CTAD一起使用?
這段代碼在gcc9.2中工作正常,但是在clang8中失敗了
template <typename int_t=int, typename float_t=float>
struct my_pair {
int_t first;
float_t second;
};
template<typename ... ts>
my_pair(ts...) -> my_pair<ts...>;
int main() {
my_pair x{.first = 20, .second = 20.f};
static_assert( std::is_same_v<decltype(x.first), int> );
static_assert( std::is_same_v<decltype(x.second), float> );
}
這應該是有效的嗎?
請參閱https://godbolt.org/z/KtNI43上的示例
是的,這應該是有效的。
CTAD的工作方式是我們對一組合成的構造函數執行重載解析,以確定類模板參數是什么。 從C ++ 17開始,那個合成的構造函數集只是基於主模板的構造函數和演繹指南(我正在更改模板參數名稱,因為我發現它們非常混亂):
template <class T=int, class U=float>
struct my_pair {
T first;
U second;
};
// default constructor
template <class T=int, class U=float>
auto __f() -> my_pair<T, U>;
// copy candidate
template <class T=int, class U=float>
auto __f(my_pair<T, U>) -> my_pair<T, U>;
// deduction guide
template <class... T>
auto __f(T...) -> my_pair<T...>;
C ++ 20添加了一個新的聚合扣除候選者。 對於initializer-list或specified-initializer-list的每個元素,我們選擇聚合的相應元素並使用其類型作為新候選。 對於
my_pair x{.first = 20, .second = 20.f};
的類型的first
是T
和類型second
是U
,因此:
// aggregate deduction candidate
template <class T=int, class U=float>
auto __f(T, U) -> my_pair<T, U>;
現在,我將這四個候選作為函數編寫(因為我發現它更容易將它們視為函數),但是措辭將它們定義為假設類類型的構造函數。 因此,當我們使用{.first = 20, .second = 20.f}
執行重載解析時,如果你眯起它有點工作。
最后一個候選人是最佳候選人(只有總計扣除候選人和扣除指南是可行的,總計扣除候選人更專業),所以我們最終得到my_pair<int, float>
。
完成CTAD后,我們現在重新開始並有效地做到了
my_pair<int, float> x{.first = 20, .second = 20.f};
哪個當然有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.