সি ++ 11 ইউনিফর্ম ইনিশিয়েশন কি পুরানো স্টাইল সিনট্যাক্সের প্রতিস্থাপন?


172

আমি বুঝতে পেরেছি যে সি ++ 11 এর অভিন্ন সূচনা ভাষায় কিছু সিনট্যাক্টিকাল অস্পষ্টতা সমাধান করে, তবে অনেকগুলি বর্জন স্ট্রোস্ট্রপের উপস্থাপনাগুলিতে (বিশেষত যাঁরা GoingNative 2012 আলোচনার সময়), তাঁর উদাহরণগুলি মূলত এই সিনট্যাক্সটি ব্যবহার করুন যখনই তিনি অবজেক্ট তৈরি করছেন।

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

মনে রাখবেন যে আমার মনে আমি প্রাথমিকভাবে অবজেক্ট নির্মাণ সম্পর্কে আমার ব্যবহারের ক্ষেত্রে হিসাবে ভাবছি, তবে যদি বিবেচনার জন্য অন্যান্য পরিস্থিতি থাকে তবে দয়া করে আমাকে জানান।


এটি প্রোগ্রামারস.সে আরও ভাল আলোচিত বিষয় হতে পারে। এটি ভাল সাবজেক্টিভ দিকের দিকে ঝুঁকছে বলে মনে হচ্ছে।
নিকোল বোলাস

6
@ নিকলবোলাস: অন্যদিকে, আপনার চমৎকার উত্তরটি সি ++ - ফ্যাক্স ট্যাগের জন্য খুব ভাল প্রার্থী হতে পারে। আমি মনে করি না এর আগে আমাদের এই পোস্টটির জন্য একটি ব্যাখ্যা ছিল।
ম্যাথিউ এম।

উত্তর:


233

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

রিন্ডন্ড্যান্ট টাইপনেমগুলি হ্রাস করে

নিম্নোক্ত বিবেচনা কর:

vec3 GetValue()
{
  return vec3(x, y, z);
}

আমাকে কেন vec3দু'বার টাইপ করতে হবে ? সেখানে কি কোন বক্তব্য আছে? সংকলকটি ফাংশনটি কী ফিরিয়ে দেয় তা ভাল এবং ভাল জানেন। কেন আমি কেবল বলতে পারি না, "আমি এই মানগুলি দিয়ে যা ফিরিয়ে দেব তার কনস্ট্রাক্টরকে কল করুন এবং এটি ফিরিয়ে দেব?" অভিন্ন সূচনা সহ, আমি এটি করতে পারি:

vec3 GetValue()
{
  return {x, y, z};
}

সবকিছু সচল.

এমনকি আরও ভাল ফাংশন আর্গুমেন্ট জন্য। এই বিবেচনা:

void DoSomething(const std::string &str);

DoSomething("A string.");

এটি কোনও টাইপনেম টাইপ না করেই কাজ করে, কারণ std::stringকীভাবে নিজেকে স্পষ্টভাবে তৈরি করতে হয় তা জানে const char*। দারুণ. তবে সেই স্ট্রিংটি যদি আসে তবে র্যাপিডএক্সএমএল বলে। অথবা একটি লুয়া স্ট্রিং। অর্থাৎ, আসুন আমি বলি আমি আসলে স্ট্রিং আপ ফ্রন্টের দৈর্ঘ্য জানি know যে std::stringকনস্ট্রাক্টর একটি const char*উইল নেয় তার স্ট্রিংয়ের দৈর্ঘ্য নিতে হবে যদি আমি কেবল একটি পাস করি const char*

স্পষ্টভাবে যদিও একটি দৈর্ঘ্য লাগে একটি ওভারলোড আছে। কিন্তু এটা ব্যবহার করার আমি এই কাজ করতে চাই: DoSomething(std::string(strValue, strLen))। কেন সেখানে অতিরিক্ত টাইপনেম রয়েছে? সংকলকটি জানে যে প্রকারটি কী। ঠিক যেমন auto, আমরা অতিরিক্ত টাইপনামগুলি এড়াতে পারি:

DoSomething({strValue, strLen});

এটা ঠিক কাজ করে। কোনও টাইপনেম নেই, কোলাহল নেই, কিছুই নেই। সংকলকটি তার কাজটি করে, কোডটি ছোট, এবং সকলেই খুশি।

মঞ্জুর, এখানে যুক্তি রয়েছে যে প্রথম সংস্করণ ( DoSomething(std::string(strValue, strLen))) আরও সুগঠিত। এটি হ'ল স্পষ্টতই কী চলছে এবং কে কী করছে। কিছুটা হলেও সত্য; অভিন্ন সূচনা-ভিত্তিক কোডটি বোঝার জন্য ফাংশন প্রোটোটাইপটি দেখার প্রয়োজন। এটি একই কারণে কেন কেউ কেউ বলেন যে আপনার কখনই অ-নিরপেক্ষ রেফারেন্স দ্বারা প্যারামিটারগুলি পাস করা উচিত নয়: যাতে কোনও মান সংশোধন করা হচ্ছে তবে আপনি কল সাইটে দেখতে পারবেন।

তবে একই কথা বলা যেতে পারে auto; আপনি কী পান তা জানার auto v = GetSomething();জন্য সংজ্ঞাটি দেখার প্রয়োজন GetSomething। এটি autoএকবার অ্যাক্সেস পেয়ে গেলে কাছাকাছি বেপরোয়া ত্যাগের সাথে ব্যবহার করা বন্ধ করে দেয় না । ব্যক্তিগতভাবে, আমি মনে করি এটি ব্যবহার করা ভাল হয়ে যাবে। বিশেষত একটি ভাল আইডিই সহ।

কখনই সর্বাধিক ভেক্সিং পার্স পাবেন না

এখানে কিছু কোড।

class Bar;

void Func()
{
  int foo(Bar());
}

পপ কুইজ: কী foo? আপনি যদি "একটি চলক" উত্তর দিয়ে থাকেন তবে আপনি ভুল। এটি আসলে কোনও ফাংশনের প্রোটোটাইপ যা এটির পরামিতি হিসাবে একটি ফাংশন নেয় যা একটি প্রদান করে Barএবং fooফাংশনটির রিটার্ন মানটি একটি ইনট হয়।

একে সি ++ এর "সর্বাধিক ভেক্সিং পার্স" বলা হয় কারণ এটি কোনও মানুষের পক্ষে একেবারেই কোনও ধারণা রাখে না। তবে দুঃখের সাথে সি ++ এর নিয়মগুলির প্রয়োজন: এটি সম্ভবত কোনও ফাংশন প্রোটোটাইপ হিসাবে ব্যাখ্যা করা যায়, তবে এটি হবে । সমস্যা হ'ল Bar(); যে দুটি জিনিস এক হতে পারে। এটি একটি প্রকারের নাম হতে পারে Barযার অর্থ এটি একটি অস্থায়ী তৈরি করছে। অথবা এটি এমন কোনও ফাংশন হতে পারে যা কোনও প্যারামিটার নেয় না এবং একটি প্রদান করে Bar

ইউনিফর্ম সূচনাটি ফাংশন প্রোটোটাইপ হিসাবে ব্যাখ্যা করা যায় না:

class Bar;

void Func()
{
  int foo{Bar{}};
}

Bar{}সর্বদা একটি অস্থায়ী তৈরি করে। int foo{...}সর্বদা একটি পরিবর্তনশীল তৈরি করে।

এমন অনেকগুলি ক্ষেত্রে রয়েছে যেখানে আপনি ব্যবহার করতে চান Typename()তবে সি ++ এর পার্সিং বিধিগুলির কারণে সহজেই পারেন না। সাথে Typename{}, কোনও দ্বিধা নেই।

না করার কারণগুলি

আপনি ছেড়ে দেওয়া একমাত্র আসল শক্তি হ'ল সংকীর্ণ। আপনি অভিন্ন ইনিশিয়ালাইজেশন সহ একটি বৃহত্তর সাথে একটি ছোট মান আরম্ভ করতে পারবেন না।

int val{5.2};

এটি সংকলন করবে না। আপনি এটি পুরানো ফ্যাশন সূচনা দিয়ে করতে পারেন, তবে অভিন্ন সূচনা নয়।

ইনিশিয়ালাইজার তালিকাগুলি আসলে কাজ করার জন্য এই অংশটি করা হয়েছিল। অন্যথায়, প্রারম্ভিক তালিকা তালিকার ধরণের ক্ষেত্রে প্রচুর অস্পষ্ট মামলা হবে।

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

লক্ষ্য করুন যে সংকলকগণ সাধারণত আপনার এই সতর্কতার স্তরটি বেশি হলে এই ধরণের জিনিস সম্পর্কে আপনাকে সতর্ক করে দেবে। সুতরাং সত্যই, এই সমস্তটি হ'ল সতর্কতাটিকে একটি কার্যকর ত্রুটিতে পরিণত করে। কেউ কেউ বলতে পারে যে আপনার যাইহোক এটি করা উচিত;)

না করার আরও একটি কারণ রয়েছে:

std::vector<int> v{100};

এটি কি করে? এটি vector<int>একশ ডিফল্ট-নির্মিত আইটেম সহ একটি তৈরি করতে পারে । বা এটি এমন vector<int>1 টি আইটেম তৈরি করতে পারে যার মান 100। উভয় তাত্ত্বিকভাবে সম্ভব।

বাস্তবে, এটি পরেরটি করে।

কেন? ইনিশিয়ালাইজার তালিকাগুলি অভিন্ন সূচনা হিসাবে একই সিনট্যাক্স ব্যবহার করে। সুতরাং অস্পষ্টতার ক্ষেত্রে কী করা উচিত তা ব্যাখ্যা করার জন্য কিছু বিধি থাকতে হবে। নিয়মটি বেশ সহজ: যদি সংকলক একটি ব্রেস-ইনিশিয়ালাইজড তালিকার সাহায্যে কোনও ইনিশিয়ালার তালিকা নির্মাণকারী ব্যবহার করতে পারে তবে তা হবে । যেহেতু vector<int>একটি ইনিশিয়ালাইজার তালিকার কনস্ট্রাক্টর রয়েছে যা গ্রহণ করে initializer_list<int>এবং {100 a একটি বৈধ হতে পারে initializer_list<int>, সুতরাং এটি অবশ্যই হওয়া উচিত

সাইজিং কনস্ট্রাক্টর পেতে আপনার ()পরিবর্তে অবশ্যই ব্যবহার করতে হবে {}

মনে রাখবেন যে এটি যদি এমন কোনও vectorকিছু হয় যা পূর্ণসংখ্যার সাথে রূপান্তরযোগ্য না হয় তবে এটি ঘটত না। একটি ইনিশিয়াল_লিস্ট সেই vectorধরণের ইনিশিয়ালাইজার তালিকার কনস্ট্রাক্টরের সাথে খাপ খায় না , এবং তাই সংযোজকটি অন্য নির্মাণকারীদের থেকে বাছাই করতে পারে।


11
এটি +1 করেছে। আপনার উত্তরটি মুছে দিচ্ছি যেহেতু আপনার সমস্ত একই পয়েন্টটি আরও বিস্তারিতভাবে সম্বোধন করে।
আর মার্টিনহো ফার্নান্দেস

21
শেষ কথাটি কেন আমি সত্যিই পছন্দ করি std::vector<int> v{100, std::reserve_tag};। একইভাবে std::resize_tag। এটি বর্তমানে ভেক্টরের স্থান সংরক্ষণ করতে দুটি পদক্ষেপ নেয়।
Xoo

6
@ নিকলবোলাস - দুটি পয়েন্ট: আমি ভেবেছিলাম ভেক্সিং পার্সের সমস্যাটি ফু () ছিল, বার () নয়। অন্য কথায়, যদি আপনি তা করেন তবে আপনি কি int foo(10)একই সমস্যায় পড়বেন না? দ্বিতীয়ত, এটি ব্যবহার না করার আরেকটি কারণ ওভার ইঞ্জিনিয়ারিংয়ের একটি সমস্যা হতে পারে বলে মনে হয়, তবে আমরা যদি আমাদের সমস্ত অবজেক্ট ব্যবহার করে নির্মাণ করি তবে কী {}একদিন পরে রাস্তার নীচে আমি আরম্ভের তালিকার জন্য কোনও কনস্ট্রাক্টর যুক্ত করব? এখন আমার সমস্ত নির্মাণের বিবৃতি ইনিশিয়ালার তালিকার বিবৃতিতে পরিণত হয়। রিফ্যাক্টরিংয়ের ক্ষেত্রে খুব ভঙ্গুর মনে হচ্ছে। এ সম্পর্কে কোন মন্তব্য?
void.pointer

7
@ রবার্টডাইলি: "আপনি যদি তা করে থাকেন int foo(10), তবে কি আপনিও একই সমস্যায় পড়বেন না?" 10 নং একটি পূর্ণসংখ্যার আক্ষরিক, এবং একটি পূর্ণসংখ্যার আক্ষরিক কখনও কোনও টাইপনেম হতে পারে না। Bar()ভেক্সিং পার্সটি সত্য থেকে আসে যা একটি টাইপনেম বা অস্থায়ী মান হতে পারে। এটিই সংকলকটির জন্য অস্পষ্টতা তৈরি করে।
নিকল বোলাস

8
unpleasant behavior- মনে রাখতে একটি নতুন স্ট্যান্ডার্ড শব্দ রয়েছে:>
he

64

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

নিম্নলিখিত কোডটি দেখুন:

vec3 GetValue()
{
  <lots and lots of code here>
  ...
  return {x, y, z};
}

প্রথমবারের মতো উপরের কোডটি পড়ছেন এমন কেউ সম্ভবত রিটার্নের স্টেটমেন্টটি তাত্ক্ষণিকভাবে বুঝতে পারবেন না কারণ তিনি যখন এই লাইনে পৌঁছবেন ততক্ষণে তিনি রিটার্নের ধরণটি ভুলে যাবেন। রিটার্নের ধরণটি দেখতে এবং রিটার্নের বিবৃতিটি পুরোপুরি বোঝার জন্য এখন তাকে ফাংশন স্বাক্ষরে ফিরে যেতে হবে বা কিছু আইডিই বৈশিষ্ট্য ব্যবহার করতে হবে।

এবং এখানে আবার কারও পক্ষে প্রথমবার কোডটি পড়ার পক্ষে আসলে কী তৈরি হচ্ছে তা বোঝা সহজ নয়:

void DoSomething(const std::string &str);
...
const char* strValue = ...;
size_t strLen = ...;

DoSomething({strValue, strLen});

উপরের কোডটি ভঙ্গ হতে চলেছে যখন কেউ সিদ্ধান্ত নিয়েছে যে ডসোমথিংয়ের সাথে অন্য কোনও স্ট্রিং ধরণের সমর্থন করা উচিত এবং এই ওভারলোডটি যুক্ত করুন:

void DoSomething(const CoolStringType& str);

যদি কুলস্ট্রিংটাইপ এমন কোনও কনস্ট্রাক্টর হয়ে থাকে যা একটি কনস্টের চার * এবং একটি সাইজ_টি নেয় (ঠিক তেমনি স্ট্যান্ড :: স্ট্রিংও করে) তবে ডসোমিংথিং-এ কল ({strValue, strLen the) ফলস্বরূপ একটি অস্পষ্টতা ত্রুটি ঘটবে।

আসল প্রশ্নের আমার উত্তর:
না, ইউনিফর্ম ইনিশিয়ালেশনটিকে পুরানো স্টাইলের কনস্ট্রাক্টর সিনট্যাক্সের প্রতিস্থাপন হিসাবে ভাবা উচিত নয়।

এবং আমার যুক্তিটি হ'ল:
দুটি বিবৃতিতে যদি একই ধরণের অভিপ্রায় না থাকে তবে সেগুলি দেখতে একই রকম হওয়া উচিত নয়। অবজেক্ট ইনিশিয়ালাইজেশন সম্পর্কে দুটি ধরণের ধারণা রয়েছে:
1) এই সমস্ত আইটেম নিন এবং আমি যে জিনিসটি আরম্ভ করছি সেগুলিতে এগুলি pourালা।
2) গাইড হিসাবে প্রদত্ত এই আর্গুমেন্টগুলি ব্যবহার করে এই বস্তুটি তৈরি করুন।

# 1 ধারণা ব্যবহারের উদাহরণ:

struct Collection
{
    int first;
    char second;
    double third;
};

Collection c {1, '2', 3.0};
std::array<int, 3> a {{ 1, 2, 3 }};
std::map<int, char> m { {1, '1'}, {2, '2'}, {3, '3'} };

# 2 ধারণার ব্যবহারের উদাহরণ:

class Stairs
{
    std::vector<float> stepHeights;

public:
    Stairs(float initHeight, int numSteps, float stepHeight)
    {
        float height = initHeight;

        for (int i = 0; i < numSteps; ++i)
        {
            stepHeights.push_back(height);
            height += stepHeight;
        }
    }
};

Stairs s (2.5, 10, 0.5);

আমি মনে করি এটি একটি খারাপ জিনিস যা নতুন স্ট্যান্ডার্ডটি এইভাবে সিঁড়ি শুরু করতে দেয়:

Stairs s {2, 4, 6};

... কারণ এটি নির্মাণকারীর অর্থকে অবিচ্ছিন্ন করে দেয়। এর মতো সূচনাটি দেখতে কেবল # 1 ধারণার মতো দেখায়, তবে তা নয়। এটি অবজেক্টের মধ্যে ধাপে উচ্চতার তিনটি পৃথক মান ingালছে না, যদিও এটি দেখতে এটির মতো দেখাচ্ছে। এবং আরও গুরুত্বপূর্ণ বিষয়, যদি উপরের মতো সিঁড়িগুলির একটি গ্রন্থাগার বাস্তবায়ন প্রকাশিত হয় এবং প্রোগ্রামাররা এটি ব্যবহার করে চলেছে এবং তারপরে যদি গ্রন্থাগার বাস্তবায়নকারী পরে সিঁড়িতে একটি আরম্ভকারী_লিস্ট নির্মাণকারী যুক্ত করেন তবে সমস্ত কোড যা ইউনিফর্ম ইনিশিয়েশন সহ সিঁড়ি ব্যবহার করে আসছে সিনট্যাক্স ভেঙে যাচ্ছে।

আমি মনে করি যে ইউনিফর্ম ইনিশিয়ালাইজেশন কীভাবে ব্যবহৃত হয়, অর্থাত্ সমস্ত সূচনাতে সমানভাবে, বা যেমন আমি দৃ strongly়ভাবে পরামর্শ দিই, প্রাথমিকভাবে এই দুটি ধারণা পৃথক করে এবং এভাবে প্রোগ্রামারের পাঠকের উদ্দেশ্যে প্রোগ্রামারের উদ্দেশ্য স্পষ্ট করার বিষয়ে একটি সাধারণ সম্মেলনে সি ++ সম্প্রদায়ের একমত হওয়া উচিত think কোড.


আফ্রিকাথ:
পুরাতন বাক্য গঠনটির প্রতিস্থাপন হিসাবে আপনি ইউনিফর্ম ইনিশিয়ালাইজেশনটিকে ভাবেন না, এমন আরও একটি কারণ এখানে এবং কেন আপনি সমস্ত সূচনাগুলির জন্য ব্রেস চিহ্ন চিহ্নিত করতে পারেন না:

বলুন, অনুলিপি তৈরির জন্য আপনার পছন্দসই বাক্য গঠনটি হ'ল:

T var1;
T var2 (var1);

এখন আপনি ভাবেন যে আপনার সমস্ত সূচনাটি নতুন ব্রেস সিনট্যাক্সের সাথে প্রতিস্থাপন করা উচিত যাতে আপনি আরও সামঞ্জস্যপূর্ণ হতে পারেন (এবং কোডটি দেখতে পাবেন)। তবে ধনুর্বন্ধনী ব্যবহার করে সিনট্যাক্স কাজ করে না যদি টাইপ টি সমষ্টিগত হয়:

T var2 {var1}; // fails if T is std::array for example

48
আপনার কাছে যদি এখানে << প্রচুর এবং প্রচুর কোড>> থাকে তবে আপনার কোডটি সিনট্যাক্স নির্বিশেষে বুঝতে অসুবিধা হবে।
কেভিন

8
আইএমও ছাড়াও এটি আপনার আইডিইয়ের কর্তব্য it এটি কী ধরণের ফিরছে তা আপনাকে অবহিত করা (উদাহরণস্বরূপ হোভারিংয়ের মাধ্যমে)। অবশ্যই যদি আপনি একটি আইডিই ব্যবহার করবেন না, আপনি নিজেকে উপরে :) বোঝা নেন
abergmeier

4
@ টমমিট আপনি যা বলছেন তার কিছু অংশের সাথে আমি একমত। যাইহোক, autoবনাম স্পষ্টত ধরণের ঘোষণার বিতর্ক হিসাবে একই আত্মায় আমি ভারসাম্যের পক্ষে যুক্তি দেব: ইউনিফর্ম ইনিশিয়েলাইজাররা টেমপ্লেট মেটা-প্রোগ্রামিং পরিস্থিতিতে বেশ বড় সময় কাটান যেখানে টাইপটি সাধারণত বেশ সুস্পষ্ট obvious এটি -> decltype(....)আগুনের জন্য যেমন আপনার অনাঙ্কর জটিল পুনরাবৃত্তি এড়াতে পারে যেমন সহজ অনলাইন ফাংশন টেম্পলেটগুলির জন্য (আমাকে কাঁদিয়েছে)।
শেঠ

5
" তবে টাইপ টি সমষ্টিগত হলে ব্রেস ব্যবহার করে সিনট্যাক্সটি কাজ করে না: " নোট করুন এটি ইচ্ছাকৃত, প্রত্যাশিত আচরণের পরিবর্তে মানকটিতে একটি প্রতিবেদন করা ত্রুটি।
নিকল বোলাস

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

-3

যদি আপনার merely copy their parametersনির্মাতারা সংশ্লিষ্ট শ্রেণীর ভেরিয়েবলগুলিতে শ্রেণীর in exactly the same orderঅভ্যন্তরে ঘোষিত হয়, তবে অভিন্ন সূচনাটি ব্যবহার করা অবশেষে কনস্ট্রাক্টরকে কল করার চেয়ে দ্রুত (তবে একেবারে অভিন্নও হতে পারে) হতে পারে।

স্পষ্টতই, এটি এই সত্যটি পরিবর্তন করে না যে আপনাকে অবশ্যই সর্বদা নির্মাতা ঘোষণা করতে হবে।


2
আপনি বলেন কেন এটি দ্রুত হতে পারে?
jbcoe

এটি ভুল। একটা কন্সট্রাকটর ঘোষণা করার কোন প্রয়োজন নেই: struct X { int i; }; int main() { X x{42}; }। এটিও ভুল, যে ইউনিফর্ম সূচনাটি মান শুরুর চেয়ে দ্রুততর হতে পারে।
টিম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.