簡體   English   中英

有沒有辦法折疊C ++ 17中的初始化列表

[英]Is there a way to fold an initializer list in C++17

與使用參數包相反,有什么方法可以折疊初始化列表? 我的問題是我有一個重載的構造函數,並且我想根據是否使用{}來調用不同的構造函數。 這似乎可以與初始化列表一起使用,該列表可以在我使用{}時隱藏我的另一個參數構造函數,而不是在我僅使用()構造它時,但是如果我使用不隱藏我的參數包,則失敗另一個參數構造函數。

另外,我還看到人們在折疊表達式中附加了void,這在我提到cppreference時沒有任何意義,在程序中似乎也沒有任何區別。

編輯:根據要求,一個示例來說明問題:

#include <iostream>
#define USE_PARAMETER_PACK false

template<typename T>
struct Mega
{
    int d;
    T* arr;
    Mega(int d) : d(d), arr(new T[d]) {}

    Mega(int d, T u) : d(d), arr(new T[d])
    {
        std::fill(arr, arr + d, static_cast<T>(u));
    }
#if USE_PARAMETER_PACK == true
    template<typename ...Ts>
    Mega(Ts&& ... vals) : d(sizeof...(Ts)), arr(new T[sizeof...(Ts)])
    {
        // fills the array with the arguments at compile time
        int i = 0;
        (void(arr[i++] = static_cast<T>(vals)), ...);
    }
#else
    template<typename U>
    Mega(const std::initializer_list<U>& list) : d(list.size()), arr(new T[d])
    {
        auto it = list.begin();
        //int i = 0;
        //((arr[i++] = (list)), ...);
        for (size_t i = 0; i < d; ++i, ++it)
            arr[i] = static_cast<T>(*it);
    }
#endif
};

template<typename T>
std::ostream& operator<<(std::ostream& os, const Mega<T>& m)
{
    for (size_t i = 0; i < m.d; ++i)
        os << m.arr[i] << "\t";
    return os;
}

int main()
{
    int* k;
    k = new int[2];
    k[0] = 2;
    k[1] = 3;
    Mega<int> l( k[0] );
    // hides 1 argument ctor through {} invocation if using initializer_list,
    // not so with parameter pack
    Mega<int> m({ k[0]}); 
    Mega<int> n(k[0], k[1]);
    // hides 2 argument ctor through {} invocation if using initializer list
    // not so with parameter pack
    Mega<int> o({ k[0], k[1] }); 
    std::cout << l << "\n";
    std::cout << m << "\n";
    std::cout << n << "\n";
    std::cout << o << "\n";

    return 0;
}

注意注釋掉的部分,我希望能夠做這樣的事情,以便在編譯時確定已知大小參數列表的填寫過程,而不是使用for循環。 應該為第一個cout打印一些垃圾值,為第二個cout打印2(至少在MSVC2017中這樣,不知道此隱藏機制是否符合標准)。 請注意,如果將define設置為true,則可以使用參數pack ctor,但是即使使用{}語法,它也無法隱藏一個參數ctor。

Edit2:為了最大程度的方便,進一步更新了代碼,只需將define更改為true即可看到參數包無法使用{}語法隱藏1和2參數構造函數,而初始化器列表ctor可以做到。

鏈接:使用初始化列表: http : //coliru.stacked-crooked.com/a/7b876e1dfbb18d73輸出:

0   0   

2   

3   3   

2   3   

使用參數包: http : //coliru.stacked-crooked.com/a/11042b2fc45b5259輸出:

0   0   

0   0   

3   3   

3   3   

因為在編譯時不知道 initializer_list的長度(特別是,具有不同數量元素的不同調用站點調用同一函數),所以不可能對其進行任何constexpr處理。 (相關的成員函數 constexpr ,但是不能在函數參數上使用它們。)特別是fold表達式需要一個參數包,其大小始終是一個常量表達式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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