Есть ли способ сложить список инициализатора в C ++ 17 - PullRequest
0 голосов
/ 07 апреля 2019

Есть ли способ свернуть список инициализаторов, в отличие от использования пакета параметров?Моя проблема в том, что у меня сильно перегружен конструктор, и я хочу вызывать разные конструкторы в зависимости от того, использую я {} или нет.Похоже, что это нормально работает со списком инициализатора, которому удается скрыть мой другой конструктор с одним аргументом, когда я использую {}, а не когда я просто создаю его с (), но происходит сбой, если я использую пакет параметров, который нескрыть мой другой конструктор с одним аргументом.

Кроме того, я заметил, что люди добавляют 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 и 2 для второго (по крайней мере, в MSVC2017, нет понятия, соответствует ли этот механизм сокрытия стандарту).Обратите внимание, что если для определения define задано значение true, вы можете использовать пакет параметров ctor, но он не сможет скрыть один аргумент ctor даже с синтаксисом {}.

Edit2: дальнейшее обновление кода для максимального удобства, простоизмените определение на 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   

1 Ответ

2 голосов
/ 02 мая 2019

Поскольку длина initializer_list равна , неизвестна во время компиляции (в частности, разные сайты вызовов с разным количеством элементов вызывают одну и ту же функцию), невозможно длявыполнить любую constexpr обработку на нем.(Соответствующие функции-члены являются constexpr, но их нельзя использовать как таковые для параметра функции.) В частности, для выражения сгиба требуется пакет параметров, размер которого равенвсегда постоянное выражение.

...