Как использовать инициализацию целочисленного списка в фигурных скобках для конструктора в С++?

Я пытаюсь, но не могу создать конструктор для своего класса, который принимает целочисленные аргументы (которые позже могут измениться на какой-то пользовательский тип данных) через инициализацию списка в фигурных скобках, как классический старый int a[]{0,1,2}. Вот мой код

#include<iostream>
using namespace std;

class class_a {
    private:
        int ptr;
    public:
        class_a() {};
        template<typename ... Args>
        class_a(Args&& ... args) : ptr((args)...) {}
};

int main()
{
    class_a c1{0}; //works
    //class_a c2[]{0,1,2}; //doesnt works
}

Мне нужен вывод, в котором переменная ptr может быть инициализирована как массив целых чисел {0,1,2} (опять же, только сейчас — позже он может измениться на любой сложный тип данных)

Что вы имеете в виду под int a{0,1,2}? Как вы думаете, что это делает или что вы хотите, чтобы это делало?

cigien 13.02.2023 17:21

Вы пытаетесь инициализировать одно целое с 3 значениями: ptr(0, 1, 2) - что недопустимо.

Amir Kirsh 13.02.2023 17:22

Вы хотели, чтобы int ptr был указателем, как int* ptr? Пожалуйста, избегайте использования указателей, особенно необработанных указателей.

Thomas Weller 13.02.2023 17:22

Классический старый int a{0,1,2}; генерирует ошибку: лишние элементы в скалярном инициализаторе.

Eljay 13.02.2023 17:28

Вам нужен один class_a с тремя значениями внутри или три экземпляра class_a? Написав class_a c2[], вы получите массив class_a объектов.

Ben Voigt 13.02.2023 18:09

Код в вопросе немного изменился с тех пор, как я ответил (class_a c2{0,1,2}; сильно отличается от class_a c2[]{0,1,2};). Новый код в вопросе, который, как вы утверждаете, не работает, работает просто отлично

Ted Lyngmo 13.02.2023 18:14

Я хочу внутри три значения (а не три экземпляра class_a) @Ben Voigt;

rupsagar 14.02.2023 04:47

Означает ли это, что ptr теперь представляет собой массив из трех целых чисел? Я хочу, чтобы ptr был массивом. Как это сделать? @ТедЛингмо

rupsagar 14.02.2023 04:49

@rupsagar Ваш оригинал, class_a c2{0,1,2};, пытался создать один экземпляр class_a, а не три экземпляра class_a, и на это отвечает мой ответ. ptr становится std::vector<int> (что похоже на массив).

Ted Lyngmo 14.02.2023 07:16

@rupsagar Я также добавил версию, в которой ptr — настоящий массив.

Ted Lyngmo 14.02.2023 07:50
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
10
99
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Поскольку класс не является шаблоном класса (или чем-то, говорящим о том, сколько элементов должно быть в переменной «ptr»), я предполагаю, что вам действительно нужен std::vector<int>, который можно инициализировать так, как вы хотите:

#include <utility>
#include <vector>

class class_a {
private:
    std::vector<int> ptr;

public:
    class_a() = default;

    template <typename... Args>
    class_a(Args&&... args) : ptr{std::forward<Args>(args)...} {}
    // with perfect forwarding in case you change to a user-defined type later
};
int main() {
    class_a c1{0};        // works
    class_a c2{0, 1, 2};  // now works
}

Если вы действительно хотите, чтобы ptr был массивом, вам нужно сделать class_a шаблон класса:

template<std::size_t N>
class class_a {
private:
    int ptr[N];            // now an array

public:
    class_a() = default;

    template <typename... Args>
    class_a(Args&&... args) : ptr{std::forward<Args>(args)...} {}
};

// deduction guide
template<class... Args> class_a(Args&&...) -> class_a<sizeof...(Args)>;

Но обратите внимание, что class_a<N> с разными N теперь являются разными типами, в отличие от того, если вы используете std::vector<int> в качестве переменной-члена.

Ваше второе решение великолепно; Я не знал об этом использовании шаблона класса. Просто хотел уточнить несколько вещей: 1. если я хочу также определить тип указателя ptr в качестве шаблона, чтобы я мог его использовать, определите class_a a1 = {0,1,2}, а также class_a a2 = {0.0 , 1.0, 2.0}... как мне это сделать? 2. Видите ли вы какие-либо потенциальные недостатки использования этого типа класса для определения матриц, таких как class_a mat = {{0,1,2}, {3,4,5}}? как мне это реализовать?

rupsagar 14.02.2023 08:35

Если вы хотите, чтобы ptr был указателем, а не массивом, предлагаю спрятать указатель в умный указатель, например std::unique_ptr<int[]> (пример) ​​— но это значит, что вам нужно отслеживать размер данных в отдельном переменная (что vector<int> делает для вас автоматически). Если class_a сам по себе является шаблоном класса, как в моем втором примере, c1 и c2 являются разными типами, поэтому присваивание, сравнение и т. д. не происходит естественным образом. Вам придется проделать большую работу, если вы хотите, чтобы два разных типа class_a<N> использовались вместе.

Ted Lyngmo 14.02.2023 09:04

Другие вопросы по теме