স্ট্যান্ড :: জোড়ের মধ্যে প্রারম্ভিক তালিকা


26

এই কোড:

#include <iostream>
#include <string>

std::pair<std::initializer_list<std::string>, int> groups{ { "A", "B" }, 0 };

int main()
{
    for (const auto& i : groups.first)
    {
        std::cout << i << '\n';
    }
    return 0;
}

সংকলন করে কিন্তু সেগফোল্ট দেয়। কেন?

জিসিসি 8.3.0 এবং অনলাইন সংকলকগুলিতে পরীক্ষিত।


1
সুবিধার জন্য: গডবোল্টের সাথে এবং বাইরে লিঙ্ক std::pair
ম্যাক্স ল্যাংফোফ

উত্তর:


24

std::initializer_listসংরক্ষণ করার উদ্দেশ্যে নয়, এটি কেবল ... ভাল আরম্ভের জন্য। অভ্যন্তরীণভাবে এটি কেবল প্রথম উপাদান এবং আকারের জন্য একটি পয়েন্টার সঞ্চয় করে। আপনার std::stringকোডগুলিতে বস্তুগুলি অস্থায়ী এবং উভয়ই initializer_listতাদের মালিকানা নেয় না, তাদের জীবন বাড়ায় না, কপিও দেয় না (কারণ এটি কোনও ধারক নয়) সুতরাং তারা সৃষ্টির পরপরই সুযোগের বাইরে চলে যায়, তবে আপনার initializer_listএখনও তাদের কাছে একটি পয়েন্টার রয়েছে। এজন্য আপনি বিভাগের ত্রুটি পান।

সংরক্ষণের জন্য আপনার পছন্দসই ধারক ব্যবহার করা উচিত, যেমন std::vectorবা std::array


এটি আমাকে সংকুচিত করে তোলে। নির্বোধ ভাষা :(
অরবিট

1
@ লাইটনেসেসেস উইথমোনিকার সাথে আমার প্রচুর গরুর মাংস রয়েছে initializer_list। কেবল স্থানান্তরিত অবজেক্টগুলি ব্যবহার করা সম্ভব নয়, সুতরাং উদাহরণস্বরূপ আপনি অনন্য_পিত্তরের ভেক্টরের সাথে তালিকা init ব্যবহার করতে পারবেন না। আকার initializer_listকোনও সংকলন-সময় ধ্রুবক নয়। এবং সত্য যে std::vector<int>(3)এবং std::vector<int>{3}সম্পূর্ণ ভিন্ন জিনিস। আমাকে দু: খিত করে তোলে :(
বলভ

হ্যাঁ একই ... :(
অরবিট

3

আমি আরও কিছু বিশদ যুক্ত করব। অন্তর্নিহিত অ্যারে std::initializer_listঅস্থায়ী হিসাবে একই ধরণের আচরণ করে। নিম্নলিখিত শ্রেণীর বিবেচনা করুন:

struct X
{
   X(int i) { std::cerr << "ctor\n"; }
   ~X() { std::cerr << "dtor\n"; }
};

এবং নিম্নলিখিত কোডটিতে এর ব্যবহার:

std::pair<const X&, int> p(1, 2);
std::cerr << "barrier\n";

এটি প্রিন্ট আউট

ctor
dtor
barrier

যেহেতু প্রথম লাইনে, টাইপের একটি অস্থায়ী উদাহরণ Xতৈরি করা হয় (কনস্ট্রাক্টর থেকে রূপান্তর করে 1) এবং ধ্বংসও হয়। এতে সঞ্চিত রেফারেন্সটি pতখন ঝোলা।

যেমন std::initializer_list, আপনি যদি এটি এভাবে ব্যবহার করেন:

{
   std::initializer_list<X> l { 1, 2 };
   std::cerr << "barrier\n";
}

তারপরে, অন্তর্নিহিত (অস্থায়ী) অ্যারে যতক্ষণ না lপ্রস্থান হয় ততক্ষণ বিদ্যমান । সুতরাং, আউটপুট হয়:

ctor
ctor
barrier
dtor
dtor

তবে আপনি যদি স্যুইচ করেন

std::pair<std::initializer_list<X>, int> l { {1}, 2 };
std::cerr << "barrier\n";

আউটপুট আবার

ctor
dtor
barrier

অন্তর্নিহিত (অস্থায়ী) অ্যারে কেবল প্রথম লাইনে বিদ্যমান line lএরপরে উপাদানগুলিতে পয়েন্টারকে ডিফার করা হলে অপরিবর্তিত আচরণের ফলাফল হয়।

লাইভ ডেমো এখানে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.