সি ++ কাঠামোর সূচনা


278

নীচে উল্লিখিত অনুসারে কি সি ++ তে স্ট্রাইকগুলি আরম্ভ করা সম্ভব?

struct address {
    int street_no;
    char *street_name;
    char *city;
    char *prov;
    char *postal_code;
};
address temp_address =
    { .city = "Hamilton", .prov = "Ontario" };

এখানে এবং এখানে লিঙ্কগুলি উল্লেখ করে যে এই স্টাইলটি কেবলমাত্র সিটিতে ব্যবহার করা সম্ভব যদি তাই হয় তবে কেন এটি সি ++ এ সম্ভব নয়? এটি সি ++ এ প্রয়োগ করা হয়নি কেন এমন কোনও অন্তর্নিহিত প্রযুক্তিগত কারণ রয়েছে বা এই স্টাইলটি ব্যবহার করা খারাপ অভ্যাস। আমি আরম্ভের এই পদ্ধতিটি ব্যবহার করতে পছন্দ করি কারণ আমার কাঠামো বড় এবং এই শৈলীটি কোন সদস্যকে কোন মান নির্ধারিত হয়েছে তার স্পষ্ট পাঠযোগ্যতা দেয়।

যদি অন্য উপায় আছে যার মাধ্যমে আমরা একই পাঠযোগ্যতা অর্জন করতে পারি তবে দয়া করে আমার সাথে ভাগ করুন।

এই প্রশ্নটি পোস্ট করার আগে আমি নীচের লিঙ্কগুলি উল্লেখ করেছি

  1. এআইএক্সের জন্য সি / সি ++
  2. চলক সহ সি স্ট্রাকচারের সূচনা
  3. সি ++ তে ট্যাগ সহ স্থির কাঠামো সূচনা
  4. সি ++ 11 সঠিক কাঠামোর সূচনা

20
বিশ্বের ব্যক্তিগত দৃষ্টিভঙ্গি: আপনাকে সি স্টোরের এই স্টাইল অবজেক্টের আরম্ভের প্রয়োজন নেই কারণ এর পরিবর্তে আপনার কনস্ট্রাক্টর ব্যবহার করা উচিত।
ফিলিপ কেন্ডল

7
হ্যাঁ আমি এটি ভেবেছিলাম, তবে আমার বড় স্ট্রাকচারের একটি অ্যারে রয়েছে। আমার পক্ষে এইভাবে ব্যবহার করা সহজ এবং পঠনযোগ্য। আপনার কি কনস্ট্রাক্টর ব্যবহারের সূচনা করার কোনও স্টাইল / ভাল অনুশীলন রয়েছে যা আরও ভাল পাঠযোগ্যতা দেয়।
দিনেশ পিআর

2
আপনি কি কনস্ট্রাক্টরের সাথে সম্মিলিতভাবে বুস্ট প্যারামিটার লাইব্রেরি বিবেচনা করেছেন? boost.org/doc/libs/1_50_0/libs/parameter/doc/html/index.html
টনি

18
প্রোগ্রামিং সম্পর্কিত এতটা সম্পর্কিত নয়: এই ঠিকানাটি কেবলমাত্র মার্কিন যুক্তরাষ্ট্রে কার্যকর হয়। ফ্রান্সে, আমাদের কোনও "প্রদেশ" নেই, বিশ্বের অন্যান্য অঞ্চলে কোনও পোস্টাল কোড নেই, বন্ধুর এক বৃদ্ধা মা এমন ছোট্ট গ্রামে থাকেন যে তার ঠিকানা "Ms X, ডাক-কোড ছোট-গ্রামের নাম "(হ্যাঁ, কোনও রাস্তা নেই)। সুতরাং সাবধানতার সাথে বিবেচনা করুন যে কোনও কার্যকর ঠিকানা বাজারে আপনি এতে প্রয়োগ করবেন;)
ম্যাথিউ এম।

5
@MatthieuM। মার্কিন যুক্তরাষ্ট্রে কোনও প্রদেশ নেই (এটি কানাডার ফর্ম্যাট হতে পারে?) তবে এমন রাজ্য, অঞ্চল, এমনকি এমন ছোট্ট গ্রামও রয়েছে যা রাস্তাগুলির নামকরণ করতে বিরক্ত করে না। সুতরাং ঠিকানা কনফারেন্সের বিষয়টি এখানেও প্রযোজ্য।
টিম

উত্তর:


166

আপনি যদি প্রতিটি আরম্ভকারী মানটি কী তা পরিষ্কার করতে চান তবে কেবল প্রতিটি মন্তব্যে একাধিক লাইনে এটি বিভক্ত করুন:

address temp_addres = {
  0,  // street_no
  nullptr,  // street_name
  "Hamilton",  // city
  "Ontario",  // prov
  nullptr,  // postal_code
};

7
আমি ব্যক্তিগতভাবে এই স্টাইলটি পছন্দ করি এবং তার প্রস্তাব দিই
দীনেশ পিআর

30
এটি করার মধ্যে পার্থক্য কী এবং ক্ষেত্রটি নিজেই আরও যথাযথভাবে অ্যাক্সেসের জন্য ডট স্বরলিপি ব্যবহার করে, এটি এমন নয় যে উদ্বেগের কারণ যদি আপনি কোনও স্থান সঞ্চয় করছেন। ধারাবাহিক থাকার এবং রক্ষণাবেক্ষণযোগ্য কোড লেখার ক্ষেত্রে আমি সত্যিই সি ++ প্রোগ্রামার পাই না, তারা মনে হয় যে তাদের কোডটি আলাদা করে দেওয়ার জন্য তারা সর্বদা আলাদা কিছু করতে চায়, কোডটি বোঝানো হচ্ছে যে সমস্যার সমাধান হওয়া উচিত নয় তা প্রতিফলিত করার জন্য নিজের মতো করে একটি প্রতিমা, নির্ভরযোগ্যতা এবং রক্ষণাবেক্ষণের স্বাচ্ছন্দ্যের লক্ষ্যে।

5
@ ব্যবহারকারী ১০৩৪০০০ ভাল, এক্ষেত্রে আপনি আপনার সদস্যদের যে অর্ডারে রেখেছেন সেটি সর্বাধিক গুরুত্বপূর্ণ। আপনি যদি আপনার কাঠামোর মাঝখানে কোনও ক্ষেত্র যোগ করেন তবে আপনাকে এই কোডটিতে ফিরে যেতে হবে এবং আপনার নতুন প্রারম্ভিককরণটি সঠিকভাবে স্পষ্ট করতে হবে যা শক্ত এবং বিরক্তিকর। ডট স্বরলিপি দিয়ে, আপনি কেবল অর্ডার নিয়ে বিরক্ত না করে তালিকার শেষে আপনার নতুন সূচনাটি রাখতে পারেন। আপনি যদি char*কাঠামোর উপরে বা নীচে অন্য সদস্যদের মধ্যে একটির মতো একই ধরণের (যেমন ) যুক্ত করতে চান তবে ডট নোটেশনটি নিরাপদ because কারণ এগুলিকে অদলবদলের কোনও ঝুঁকি নেই।
গুই 13

6
অরিপের মন্তব্য যদি ডেটা স্ট্রাকচারের সংজ্ঞা পরিবর্তিত হয়ে যায় এবং কেউ আরম্ভের সন্ধানের জন্য ভাবেন না, বা সেগুলি সন্ধান করতে পারে না বা সেগুলি সম্পাদনা করতে ভুল করে, জিনিসগুলি পৃথক হয়ে যাবে।
এডওয়ার্ড ফ্যাল্ক

3
বেশিরভাগ (সমস্ত না থাকলে) পসিক্স স্ট্রকের কোনও সংজ্ঞায়িত ক্রম থাকে না, কেবল সংজ্ঞায়িত সদস্যরা। (struct timeval){ .seconds = 0, .microseconds = 100 }সবসময় একশ মাইক্রোসেকেন্ড হবে, কিন্তু timeval { 0, 100 }একশ হতে পারে সেকেন্ড । আপনি এরকম শক্ত উপায় খুঁজে বের করতে চান না।
yyny

98

আমার প্রশ্নের কোনও সন্তোষজনক ফলাফল না হওয়ার পরে (কারণ সি ++ কাঠামোগুলির জন্য ট্যাগ-ভিত্তিক উদ্যোগ প্রয়োগ করে না), আমি যে কৌশলটি পেয়েছি তা এখানে পেয়েছি: সি ++ স্ট্রাক্টের সদস্যরা কি ডিফল্টরূপে 0 থেকে আরম্ভ হয়?

আপনার পক্ষে এটি করার পরিমাণ হবে:

address temp_address = {}; // will zero all fields in C++
temp_address.city = "Hamilton";
temp_address.prov = "Ontario";

এটি অবশ্যই আপনি মূলত যা চেয়েছিলেন তার নিকটতম (আপনি আরম্ভ করতে চান তা বাদে সমস্ত ক্ষেত্র শূন্য)।


10
এটি স্থিতিশীলভাবে অন্তর্ভুক্ত বস্তুগুলির জন্য কাজ করে না
ব্যবহারকারীর 877329

5
static address temp_address = {};কাজ করবে. পরে এটি পূরণ করা রানটাইম পর্যন্ত, হ্যাঁ। আপনি একটি স্ট্যাটিক ফাংশন যা আপনার জন্য Init করে প্রদানের মাধ্যমে এই বাইপাস করতে পারেন: static address temp_address = init_my_temp_address();
গুই 13

সি ++ 11 এ init_my_temp_addressল্যাম্বডা ফাংশন হতে পারে:static address temp_address = [] () { /* initialization code */ }();
4:54

3
খারাপ ধারণা, এটি RAII নীতি লঙ্ঘন করে।
এইচস্প্যাক্স

2
সত্যিই খারাপ ধারণা: আপনার একজন সদস্য যুক্ত করুন addressএবং আপনি যে জায়গাগুলি তৈরি করেছেন addressএবং এখন আপনার নতুন সদস্যকে আরম্ভ করবেন না এমন সমস্ত জায়গাগুলি আপনি কখনই জানতে পারবেন না ।
রহস্য_ডোক্টর


17

ক্ষেত্র শনাক্তকারীরা প্রকৃতপক্ষে সি প্রাথমিককরণ বাক্য গঠন। সি ++ তে কেবল ক্ষেত্রের নাম ছাড়াই সঠিক ক্রমে মানগুলি দিন। দুর্ভাগ্যক্রমে এর অর্থ এই যে আপনাকে সেগুলি দেওয়া দরকার (আসলে আপনি শূন্য-মূল্যবান ক্ষেত্রগুলি বাদ দিতে পারেন এবং ফলাফলটি একই হবে):

address temp_address = { 0, 0, "Hamilton", "Ontario", 0 }; 

1
হ্যাঁ আপনি সর্বদা প্রান্তিক কাঠামো সূচনাটি ব্যবহার করতে পারেন।
টেক্সাসব্রুস

3
হ্যাঁ, বর্তমানে আমি কেবল এই পদ্ধতিটি ব্যবহার করছি (সংযুক্ত কাঠামো সূচনা)। তবে আমি অনুভব করি পাঠযোগ্যতা ভাল নয়। যেহেতু আমার স্ট্রাকচার বড় তাই ইনিশিয়ালাইজারের অনেকগুলি ডেটা রয়েছে এবং কোন সদস্যটিতে কোন মান নির্ধারিত হয়েছে তা ট্র্যাক করা আমার পক্ষে কঠিন।
দিনেশ পিআর

7
@ DineshP.R। তারপরে কোনও কনস্ট্রাক্টর লিখুন!
মিস্টার লিস্টার

2
@ মিস্টারলিস্টার (বা যে কেউ) সম্ভবত আমি এই মুহুর্তে বোকামির মেঘের মধ্যে আটকে আছি, তবে নির্মাতা কীভাবে আরও ভাল হতে পারবেন তা বোঝানোর যত্ন নিচ্ছেন? আমার কাছে মনে হয় একটি প্রাথমিক নির্দেশকের তালিকায় অর্ডার-নির্ভর নামবিহীন মানগুলির একগুচ্ছ সরবরাহ করা বা কোনও নির্মাতাকে অর্ডার-ভিত্তিক নামবিহীন মান সরবরাহ করার মধ্যে কিছুটা পার্থক্য নেই ...?
ইয়ানো

1
@ আয়ানো সত্যি বলতে কী, আমি কেন সত্যিই মনে করতে পারি না যে আমি কেন একজন নির্মাতা সমস্যার উত্তর হবে। যদি মনে থাকে তবে আমি আপনার কাছে ফিরে আসব।
মিস্টার লিস্টার

13

এই বৈশিষ্ট্যটিকে মনোনীত প্রারম্ভিক বলা হয় । এটি সি 99 স্ট্যান্ডার্ডের একটি সংযোজন। তবে এই বৈশিষ্ট্যটি C ++ 11 এর বাইরে রেখে দেওয়া হয়েছে। সি ++ প্রোগ্রামিং ল্যাঙ্গুয়েজ, চতুর্থ সংস্করণ অনুসারে, বিভাগ 44.3.3.2 (সি বৈশিষ্ট্যগুলি সি ++ দ্বারা গৃহীত নয়):

সি 99 এর কয়েকটি সংযোজন (সি 98 এর সাথে তুলনা করে) সি ++ এ ইচ্ছাকৃতভাবে গৃহীত হয়নি:

[1] পরিবর্তনশীল-দৈর্ঘ্যের অ্যারে (ভিএলএএস); ভেক্টর বা গতিশীল অ্যারে কিছু ফর্ম ব্যবহার করুন

[২] মনোনীত প্রাথমিক; কনস্ট্রাক্টর ব্যবহার করুন

সি 99 ব্যাকরণে মনোনীত প্রারম্ভিক রয়েছে [আইএসও / আইইসি 9899: 2011, এন 1570 কমিটির খসড়া দেখুন - এপ্রিল 12, 2011]

7.7.৯ সূচনা

initializer:
    assignment-expression
    { initializer-list }
    { initializer-list , }
initializer-list:
    designation_opt initializer
    initializer-list , designationopt initializer
designation:
    designator-list =
designator-list:
    designator
    designator-list designator
designator:
    [ constant-expression ]
    . identifier

অন্যদিকে, সি ++ 11 এর মনোনীত প্রারম্ভিকদের নেই [আইএসও / আইইসি 14882: ২০১১, এন 3690 কমিটির খসড়া দেখুন - 15 ই মে, 2013]

8.5 প্রারম্ভিক

initializer:
    brace-or-equal-initializer
    ( expression-list )
brace-or-equal-initializer:
    = initializer-clause
    braced-init-list
initializer-clause:
    assignment-expression
    braced-init-list
initializer-list:
    initializer-clause ...opt
    initializer-list , initializer-clause ...opt
braced-init-list:
    { initializer-list ,opt }
    { }

একই প্রভাব অর্জন করতে, নির্মাণকারী বা আরম্ভকারী তালিকা ব্যবহার করুন:


9

আপনি কেবল ctor মাধ্যমে সূচনা করতে পারেন:

struct address {
  address() : city("Hamilton"), prov("Ontario") {}
  int street_no;
  char *street_name;
  char *city;
  char *prov;
  char *postal_code;
};

9
আপনি যদি এর সংজ্ঞাটি নিয়ন্ত্রণ করেন তবেই এটি ক্ষেত্রে থাকে struct address। এছাড়াও, পিওডি প্রকারগুলি প্রায়শই ইচ্ছাকৃতভাবে কোনও নির্মাণকারী এবং ডেস্ট্রাক্টর থাকে না।
ব্যবহারকারী 4815162342

7

আপনি এমনকি গি 13 এর সমাধানটি একক সূচনা বিবৃতিতে প্যাক করতে পারেন:

struct address {
                 int street_no;
                 char *street_name;
                 char *city;
                 char *prov;
                 char *postal_code;
               };


address ta = (ta = address(), ta.city = "Hamilton", ta.prov = "Ontario", ta);

দাবি অস্বীকার: আমি এই স্টাইলটি সুপারিশ করি না


এটি এখনও বিপজ্জনক কারণ এটি আপনাকে সদস্য হিসাবে যুক্ত করতে দেয় addressএবং কোডটি এখনও দশ মিলিয়ন জায়গার সাথে কেবল পাঁচটি মূল সদস্যকে আরম্ভ করার সাথে সংকলন করবে। স্ট্রাক্ট আরম্ভের সেরা অংশটি হ'ল আপনার সকল সদস্য থাকতে পারে constএবং এটি আপনাকে তাদের
সমস্তটি

7

আমি জানি এই প্রশ্নটি বেশ পুরানো, তবে আমি আরম্ভ করার অন্য একটি উপায় খুঁজে পেয়েছি, কনটেক্সটপ্র ব্যবহার করে এবং কারি করছিলাম:

struct mp_struct_t {
    public:
        constexpr mp_struct_t(int member1) : mp_struct_t(member1, 0, 0) {}
        constexpr mp_struct_t(int member1, int member2, int member3) : member1(member1), member2(member2), member3(member3) {}
        constexpr mp_struct_t another_member(int member) { return {member1, member,     member2}; }
        constexpr mp_struct_t yet_another_one(int member) { return {member1, member2, member}; }

    int member1, member2, member3;
};

static mp_struct_t a_struct = mp_struct_t{1}
                           .another_member(2)
                           .yet_another_one(3);

এই পদ্ধতিটি গ্লোবাল স্ট্যাটিক ভেরিয়েবল এবং এমনকি কনটেক্সপ্রসগুলির জন্যও কাজ করে। একমাত্র অসুবিধাটি হ'ল খারাপ রক্ষণাবেক্ষণযোগ্যতা: এই পদ্ধতিটি ব্যবহার করে অন্য কোনও সদস্যকে আরম্ভযোগ্য করে তুলতে হবে, সমস্ত সদস্য আরম্ভের পদ্ধতি পরিবর্তন করতে হবে।


1
এটি নির্মাতা প্যাটার্ন । সদস্য পদ্ধতিগুলি প্রতিবার নতুন কাঠামো তৈরির পরিবর্তে পরিবর্তিত হওয়া সম্পত্তিটির একটি রেফারেন্স ফিরিয়ে দিতে পারে
ফুচলভ

6

আমি এখানে কিছু অনুপস্থিত হতে পারে, কেন নয়:

#include <cstdio>    
struct Group {
    int x;
    int y;
    const char* s;
};

int main() 
{  
  Group group {
    .x = 1, 
    .y = 2, 
    .s = "Hello it works"
  };
  printf("%d, %d, %s", group.x, group.y, group.s);
}

আমি উপরের প্রোগ্রামটি একটি মিনিজিডব্লিউ সি ++ সংকলক এবং একটি আরডুইনো এভিআর সি ++ সংকলক দিয়ে সংকলন করেছি এবং উভয়ই প্রত্যাশার মতো দৌড়েছি। # অন্তর্ভুক্ত <cstdio>
রান_ত্যাগ_সেপ্টেম্বর

4
@ রুন_ও_রেস, এটি সি ++ স্ট্যান্ডার্ড যা দেয় কোনও কম্পাইলারের আচরণ কী হতে পারে তা বলে না says তবে এই বৈশিষ্ট্যটি সি ++ 20 এ আসছে।
জন

এটি কেবল তখনই কাজ করে যদি স্ট্রাক্টটি পড হয়। সুতরাং আপনি এটিতে কোনও নির্মাণকারী যুক্ত করলে এটি সংকলন বন্ধ হবে stop
oromoiluig

5

এটি সি ++ এ প্রয়োগ করা হয়নি। (এছাড়াও, char*স্ট্রিংস? আমি আশা করি না)।

সাধারণত আপনার এতগুলি পরামিতি থাকলে এটি মোটামুটি গুরুতর কোডের গন্ধ। তবে পরিবর্তে, কেন কেবল স্ট্রাককে মূল্য-আরম্ভ করতে হবে না এবং তারপরে প্রতিটি সদস্যকে বরাদ্দ দেওয়া হবে না?


6
"(এছাড়াও, char*স্ট্রিং? আশা করি না)" - ঠিক আছে, এটি একটি সি উদাহরণ।
এড এস

আমরা কি সি ++ তে চর * ব্যবহার করতে পারি না? বর্তমানে আমি এটি ব্যবহার করছি এবং এটি কাজ করছে (হতে পারে আমি কিছু ভুল করছি)। আমার অনুমান যে সংকলকটি "হ্যামিল্টন" এবং "অন্টারিও" এর নিয়মিত স্ট্রিং তৈরি করবে এবং কাঠামোর সদস্যদের তাদের ঠিকানা বরাদ্দ করবে। পরিবর্তে কনস্ট চর * ব্যবহার করা কি সঠিক হবে?
দিনেশ পিআর

8
আপনি ব্যবহার করতে পারেন char*তবে const char*অনেক বেশি টাইপ-সেফ এবং সকলেই কেবল ব্যবহার করেন std::stringকারণ এটি অনেক বেশি নির্ভরযোগ্য।
কুকুরছানা

ঠিক আছে. আমি যখন "নীচে উল্লিখিত হিসাবে" পড়ি তখন আমি ধরে নিয়েছিলাম এটি কোথাও থেকে অনুলিপি করা একটি উদাহরণ।
এড এস

2

আমি বৈশ্বিক ভেরিয়েবলের জন্য এটি করার এই পদ্ধতিটি পেয়েছি, এটির জন্য মূল কাঠামোর সংজ্ঞাটি পরিবর্তন করার দরকার নেই:

struct address {
             int street_no;
             char *street_name;
             char *city;
             char *prov;
             char *postal_code;
           };

তারপরে মূল কাঠামোর ধরণ থেকে উত্তরাধিকারসূত্রে প্রাপ্ত একটি নতুন ধরণের ভেরিয়েবল ঘোষণা করুন এবং ক্ষেত্র আরম্ভের জন্য কনস্ট্রাক্টর ব্যবহার করুন:

struct temp_address : address { temp_address() { 
    city = "Hamilton"; 
    prov = "Ontario"; 
} } temp_address;

সি স্টাইলের মতো বেশ মার্জিত নয় যদিও ...

স্থানীয় ভেরিয়েবলের জন্য এটির নির্মাণকারীর শুরুতে একটি অতিরিক্ত মেমসেট (এটি, 0, আকারের (* এটি)) প্রয়োজন, সুতরাং এটি স্পষ্টত খারাপ নয় এবং @ গুই 13 এর উত্তরটি আরও উপযুক্ত।

(মনে রাখবেন যে 'টেম্প_এড্রেস' 'টেম্প_এড্রেস' টাইপের একটি পরিবর্তনশীল, তবে এই নতুন ধরণটি 'ঠিকানা' থেকে উত্তরাধিকার সূত্রে পাওয়া যায় এবং যেখানে 'ঠিকানা' প্রত্যাশা করা হয় সেখানে প্রতিটি জায়গায় ব্যবহার করা যেতে পারে, তাই এটি ঠিক আছে))


1

আমি আজ একই ধরণের সমস্যার মুখোমুখি হয়েছি, যেখানে আমার এমন স্ট্রাক্ট রয়েছে যা আমি পরীক্ষার ডেটা পূরণ করতে চাই যা আমি পরীক্ষা করছি এমন কোনও ফাংশনের আর্গুমেন্ট হিসাবে পাস করা হবে। আমি এই স্ট্রাক্টগুলির একটি ভেক্টর পেতে চাই এবং প্রতিটি স্ট্রাক্টের সূচনা করার জন্য একটি লাইন পদ্ধতি আবিষ্কার করছিলাম।

আমি স্ট্রাক্টে একটি কনস্ট্রাক্টর ফাংশন দিয়ে গিয়ে শেষ করেছি, যা আমি বিশ্বাস করি আপনার প্রশ্নের কয়েকটি উত্তরেও পরামর্শ দেওয়া হয়েছিল।

কনস্ট্রাক্টরের পক্ষে যুক্তিগুলি পাবলিক সদস্য ভেরিয়েবলের একই নাম থাকতে thisপয়েন্টার ব্যবহারের প্রয়োজন হয় এটি সম্ভবত খারাপ অভ্যাস । আরও ভাল উপায় থাকলে কেউ সম্পাদনার পরামর্শ দিতে পারেন।

typedef struct testdatum_s {
    public:
    std::string argument1;
    std::string argument2;
    std::string argument3;
    std::string argument4;
    int count;

    testdatum_s (
        std::string argument1,
        std::string argument2,
        std::string argument3,
        std::string argument4,
        int count)
    {
        this->rotation = argument1;
        this->tstamp = argument2;
        this->auth = argument3;
        this->answer = argument4;
        this->count = count;
    }

} testdatum;

যা আমি আমার টেস্ট ফাংশনটিতে ফাংশনটিকে বিভিন্ন যুক্তি দিয়ে পরীক্ষা করে দেখানোর জন্য এটি ব্যবহার করতে বলেছিলাম:

std::vector<testdatum> testdata;

testdata.push_back(testdatum("val11", "val12", "val13", "val14", 5));
testdata.push_back(testdatum("val21", "val22", "val23", "val24", 1));
testdata.push_back(testdatum("val31", "val32", "val33", "val34", 7));

for (std::vector<testdatum>::iterator i = testdata.begin(); i != testdata.end(); ++i) {
    function_in_test(i->argument1, i->argument2, i->argument3, i->argument4m i->count);
}

1

এটি সম্ভব, তবে কেবল যদি আপনি যে স্ট্রাক্টের সূচনা করছেন তা হ'ল একটি পিওডি (সাধারণ পুরাতন ডেটা) স্ট্রাক্ট। এটিতে কোনও পদ্ধতি, কনস্ট্রাক্টর বা এমনকি ডিফল্ট মান থাকতে পারে না।


1

সি ++ তে সি-স্টাইল ইনিশিয়ালাইজারগুলি কন্সট্রাক্টর দ্বারা প্রতিস্থাপন করা হয়েছিল যা সংকলনের সময় দ্বারা নিশ্চিত করা যায় যে কেবলমাত্র বৈধ আরম্ভ হবে (অর্থাত্ প্রাথমিককরণের পরে অবজেক্টের সদস্যরা সামঞ্জস্যপূর্ণ)।

এটি একটি ভাল অনুশীলন, তবে কখনও কখনও প্রাক-সূচনাটি আপনার উদাহরণের মতো কার্যকর। ওওপি এটি বিমূর্ত ক্লাস বা ক্রিয়েশনাল ডিজাইনের ধরণগুলির দ্বারা সমাধান করে

আমার মতে, এই নিরাপদ উপায়ে ব্যবহার করা সরলতাটিকে মেরে ফেলে এবং কখনও কখনও সুরক্ষা বাণিজ্য বন্ধও ব্যয়বহুল হতে পারে, কারণ সহজ কোড বজায় রাখার জন্য পরিশীলিত নকশার প্রয়োজন হয় না।

বিকল্প সমাধান হিসাবে, আমি প্রায় সি-স্টাইলের মতো দেখতে সূচনাটি সহজ করার জন্য ল্যাম্বডাস ব্যবহার করে ম্যাক্রোগুলি সংজ্ঞায়িত করার পরামর্শ দিই:

struct address {
  int street_no;
  const char *street_name;
  const char *city;
  const char *prov;
  const char *postal_code;
};
#define ADDRESS_OPEN [] { address _={};
#define ADDRESS_CLOSE ; return _; }()
#define ADDRESS(x) ADDRESS_OPEN x ADDRESS_CLOSE

ADDRESS ম্যাক্রো প্রসারিত হয়

[] { address _={}; /* definition... */ ; return _; }()

যা ল্যাম্বডাকে তৈরি করে এবং কল করে। ম্যাক্রো প্যারামিটারগুলিও কমা দ্বারা পৃথক করা হয়েছে, সুতরাং আপনাকে আরম্ভকারীটিকে বন্ধনীতে লাগাতে হবে এবং পছন্দ করতে হবে

address temp_address = ADDRESS(( _.city = "Hamilton", _.prov = "Ontario" ));

আপনি জেনারালাইজড ম্যাক্রো ইনিশিয়ালাইজারও লিখতে পারেন

#define INIT_OPEN(type) [] { type _={};
#define INIT_CLOSE ; return _; }()
#define INIT(type,x) INIT_OPEN(type) x INIT_CLOSE

কিন্তু তারপরে কলটি কিছুটা কম সুন্দর

address temp_address = INIT(address,( _.city = "Hamilton", _.prov = "Ontario" ));

তবে আপনি সাধারণ আইএনআইটি ম্যাক্রো সহজেই ব্যবহার করে অ্যাড্রেস ম্যাক্রো সংজ্ঞায়িত করতে পারেন

#define ADDRESS(x) INIT(address,x)

1

জিএনইউসি ++ এ (দীর্ঘকাল আগে 2.5, থেকে অপ্রচলিত বলে মনে হচ্ছে :) উত্তরগুলি এখানে দেখুন: লে স্টাইলগুলি ব্যবহার করে সি স্ট্রাক্টের সূচনা। এটা কাজ করে, কিন্তু কিভাবে? ), এটির মতো কোনও কাঠামো সূচনা করা সম্ভব:

struct inventory_item {
    int bananas;
    int apples;
    int pineapples;
};

inventory_item first_item = {
    bananas: 2,
    apples: 49,
    pineapples: 4
};

0

এই সত্যিই ঝরঝরে উত্তর দ্বারা অনুপ্রাণিত: ( https://stackoverflow.com/a/49572324/4808079 )

আপনি লাম্বা বন্ধ করতে পারেন:

// Nobody wants to remember the order of these things
struct SomeBigStruct {
  int min = 1;
  int mean = 3 ;
  int mode = 5;
  int max = 10;
  string name;
  string nickname;
  ... // the list goes on
}

class SomeClass {
  static const inline SomeBigStruct voiceAmps = []{
    ModulationTarget $ {};
    $.min = 0;  
    $.nickname = "Bobby";
    $.bloodtype = "O-";
    return $;
  }();
}

বা, যদি আপনি খুব অভিনব হতে চান

#define DesignatedInit(T, ...)\
  []{ T ${}; __VA_ARGS__; return $; }()

class SomeClass {
  static const inline SomeBigStruct voiceAmps = DesignatedInit(
    ModulationTarget,
    $.min = 0,
    $.nickname = "Bobby",
    $.bloodtype = "O-",
  );
}

এর সাথে কিছু ত্রুটি জড়িত রয়েছে, বেশিরভাগই অচিরাচালিত সদস্যদের সাথে করণীয়। লিঙ্কযুক্ত উত্তরের মন্তব্যগুলি যা বলে তা থেকে এটি দক্ষতার সাথে সংকলন করে, যদিও আমি এটি পরীক্ষা করে দেখিনি।

সামগ্রিকভাবে, আমি কেবল এটি একটি ঝরঝরে দৃষ্টিভঙ্গি মনে করি।

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