39 / 28 / 11
Регистрация: 21.06.2019
Сообщений: 201
1

variadic pack конструктор принимающий списки инициализации

08.05.2021, 11:01. Показов 1130. Ответов 3

Пытаюсь реализовать конструктор, который бы мог вызываться следующим образом:
C++
1
Matrix<double, 2, 2> m ({3, 4}, {5, 6});
Но для этого конструктора он не может определить типы для args...:
C++
1
2
3
4
    template <typename ...Args, typename = typename std::enable_if_t<IsIteratable<Args...>::value, void>>
    Matrix(Args... args){
        mat = {args...};
    }
, где IsIteratable - это:
C++
1
2
3
4
5
6
7
8
9
10
template <typename T, typename ...OtherT>
struct IsIteratable{
    static const bool value = std::is_same_v<typename std::iterator_traits<typename T::iterator>::iterator_category(), std::random_access_iterator_tag()> || std::is_same_v<typename std::iterator_traits<typename T::iterator>::iterator_category(), std::bidirectional_iterator_tag()>
            && IsIteratable<OtherT...>::value;
};
 
template <typename T>
struct IsIteratable<T>{
    static const bool value = std::is_same_v<typename std::iterator_traits<typename T::iterator>::iterator_category(), std::random_access_iterator_tag()> || std::is_same_v<typename std::iterator_traits<typename T::iterator>::iterator_category(), std::bidirectional_iterator_tag()>;
};
Есть ли способ такой конструктор получить? Или почему он не понимает что за типы в {}? Если написать так, то он всё выполняет валидно:
C++
1
Matrix<double, 2, 2> m (std::vector<double>{3, 4}, std::vector<double>{5, 6});
или
C++
1
Matrix<double, 2, 2> m (std::initializer_list<double>{3, 4}, std::initializer_list<double>{5, 6});
Если он не способен понять что это за типы, можно ли как-то явно заставить понимать что это initializer_list? Чтобы не писать тип в параметрах при его вызове!
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.05.2021, 11:01
Ответы с готовыми решениями:

[variadic pack][cdecl]
доброе утро. рассмотрим код: http://rextester.com/ATJJT68666 #include &lt;iostream&gt;

Можно ли использовать конструктор по умолчанию и конструктор инициализации одновременно?
Можно ли использовать конструктор по умолчанию и конструктор инициализации одновременно?

Конструктор инициализации, конструктор копирования, деструктор
Я сделал почти задание по перегрузке операторов. Осталось одно, тоесть три: конструктор...

Конструктор, принимающий параметр
привет. посмотрите листинг: // Префиксный и постфиксный операторы инкремента #include &lt;iostream&gt;...

3
16082 / 8684 / 2120
Регистрация: 30.01.2014
Сообщений: 14,967
08.05.2021, 11:12 2
Цитата Сообщение от HamsterGamer Посмотреть сообщение
можно ли как-то явно заставить понимать что это initializer_list?
Так это не initializer_list, вот он и не понимает. {} - это инициализатор для уже заданного каким-либо образом типа, а не наоборот. Он становится инициализатором для initalizer_list только в том контексте, где initalizer_list уже присутствует, а не является сам по себе initalizer_list`ом.

Цитата Сообщение от HamsterGamer Посмотреть сообщение
Чтобы не писать тип в параметрах при его вызове!
Сделайте еще один конструктор с конкретными указаниями. Например такой:

C++
1
2
3
4
template <typename ...Args>
Matrix(std::initializer_list<Args>... lst) {
    //...
}
1
39 / 28 / 11
Регистрация: 21.06.2019
Сообщений: 201
08.05.2021, 11:39  [ТС] 3
DrOffset, хорошо, спасибо. {} - это получается сишный список инициализации?
Но есть еще одна проблема, возможно я некорректно реализовал конструктор, предложенный вами, но как в этом случае кастовать каждый элемент нового списка к T? Пройтись циклом и сделать обычный emplace_back или есть способ попроще?

Моя реализация:
C++
1
2
3
4
5
6
7
8
9
10
11
12
    template<typename U, typename ...Args>
    void Undress(U && first, Args&&... Others){
        mat.emplace_back();
        mat.back() = {(first)};
        Undress(Others...);
    }
    void Undress(){}
 
     template <typename ...Args>
    Matrix(std::initializer_list<Args>... lst) {
        Undress(lst...);
    }
Не работает если писать так:
C++
1
Matrix<double, 2, 2> m ({4, 5}, {3,6});
Работает если использовать типы, указанные в качестве шаблонного типа матрицы:
C++
1
    Matrix<int, 2, 2> m ({4, 5}, {3,6});
0
16082 / 8684 / 2120
Регистрация: 30.01.2014
Сообщений: 14,967
08.05.2021, 12:12 4
Лучший ответ Сообщение было отмечено HamsterGamer как решение

Решение

Цитата Сообщение от HamsterGamer Посмотреть сообщение
ак в этом случае кастовать каждый элемент нового списка к T?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template <typename T>
class Matrix {
public:
    template<typename U, typename ...Args>
    void Undress(U && first, Args&&... Others){
        mat.emplace_back(std::begin(first), std::end(first));
        Undress(std::forward<Args>(Others)...);
    }
    void Undress(){}
 
    template <typename ...Args>
    Matrix(std::initializer_list<Args>... lst) {
        Undress(lst...);
    }
    template <typename ...Args>
    Matrix(Args &&... lst) {
        Undress(std::forward<Args>(lst)...);
    }    
private:
    std::vector<std::vector<T>> mat;
};
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.05.2021, 12:12
Помогаю со студенческими работами здесь

Ошибка: не содержит конструктор принимающий обьект 2
Не хочет принимать точки, хотя есть конструктор. Помечено комментами. Подскажите, пожалуйста....

Конструктор принимающий два целочисленных значения
Добрый день существует Конструктор принимающий два целочисленных значения, как можно просмотреть...

CS1729 {} не содержит конструктор, принимающий аргументы 2
Добрый день! Пытаюсь подключить библиотеку dll к проекту, но написанные мной конструкторы и методы...

Конструктор, принимающий в качестве аргумента ссылку на объект, всё портит
Друзья! Вот корректный код: class foo { public: foo() { ...

Класс не содержит конструктор, принимающий 3 аргумента: найти ошибку в коде
Весь измучился, но компилятор неприклонен - &quot;Ошибка 1 SAYAP_labaratornaya2.Student не содержит...

Компилятор требует конструктор, принимающий аргументом экземпляр того же класса (не ссылку)
Доброго времени суток. Проблема такова: имеется ряд нижеприведённых классов (для простоты всё,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru