簡體   English   中英

C ++ 20指定的帶模板類型的初始值設定項

[英]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-listspecified-initializer-list的每個元素,我們選擇聚合的相應元素並使用其類型作為新候選。 對於

my_pair x{.first = 20, .second = 20.f};

的類型的firstT和類型secondU ,因此:

// 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.

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