সি ++ কোড কি সি ++ 03 এবং সি ++ 11 উভয়ই বৈধ হতে পারে তবে বিভিন্ন জিনিস করতে পারে?


298

সি ++ কোডের পক্ষে কি সি ++ 03 স্ট্যান্ডার্ড এবং সি ++ 11 স্ট্যান্ডার্ড উভয়ই মেনে চলতে পাওয়া সম্ভব , তবে এটি কোন মানের অধীন সংকলন করা হচ্ছে তার উপর নির্ভর করে বিভিন্ন কাজ করে?


26
আমি নিশ্চিত যে autoএরকম পরিস্থিতিতে এমন এক পরিণতি আসতে পারে
ওএমজিটিচি

8
হ্যাঁ. একটি উদাহরণটি >>যখন কোনও টেমপ্লেটে ব্যবহৃত হয়। আপনি এমন পরিস্থিতির সাথে আসতে পারেন যেখানে এটি উভয় মানের জন্য সংকলন করতে পারে। আর একটি যে আমি নিশ্চিত যে এর জন্য পরিবর্তনগুলি খুঁজে পাওয়া সহজ হবে প্রাথমিকভাবে।
ক্রিস

5
: এখানে >> পরিস্থিতি চমৎকার নিবন্ধ এর gustedt.wordpress.com/2013/12/15/...
ক্রিস

6
@ ওমগেটেচি: আমি মনে করি না যে এটির autoকারণ হতে পারে। পুরানো অর্থ সহ, একটি autoঘোষণার জন্য একটি প্রকারের নাম প্রয়োজন; নতুন অর্থ সহ, কোনও প্রকারের নাম অনুমোদিত নয়।
কিথ থম্পসন

2
এটি কীভাবে উন্মুক্ত? আপনি নিজেই অন্য একটি প্রশ্নের মাধ্যমে উল্লেখ করেছেন যে এই প্রশ্নের উত্তর "হ্যাঁ, এখানে কীভাবে হয় তার একটি উদাহরণ"। আপনি নিজের ইঙ্গিত হিসাবে প্রশ্নের একটি খুব নির্দিষ্ট উত্তর আছে।
jalf

উত্তর:


283

উত্তর একটি নির্দিষ্ট হ্যাঁ। প্লাস দিকে রয়েছে:

  • কোড যা পূর্বে স্পষ্টভাবে অনুলিপি করা অবজেক্টগুলি এখন সম্ভব হলে স্পষ্টভাবে তাদের সরানো হবে।

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

স্ট্রিং আক্ষরিক

#define u8 "abc"
const char* s = u8"def"; // Previously "abcdef", now "def"

এবং

#define _x "there"
"hello "_x // Previously "hello there", now a user defined string literal

0 এর রূপান্তর টাইপ করুন

সি ++ ১১-এ, কেবল আক্ষরিক হ'ল পূর্ণসংখ্যা নাল পয়েন্টার ধ্রুবক:

void f(void *); // #1
void f(...); // #2
template<int N> void g() {
    f(0*N); // Calls #2; used to call #1
}

পূর্ণসংখ্যা বিভাগ এবং মডুলোর পরে গোলাকার ফলাফল

সি ++ 03 এ সংকলকটিকে 0 বা দিকে বা নেতিবাচক অসীমের দিকে মঞ্জুরি দেওয়া হয়েছিল। সি ++ 11 এ 0 এর দিকে গোল করা বাধ্যতামূলক

int i = (-1) / 2; // Might have been -1 in C++03, is now ensured to be 0

নেস্টেড টেমপ্লেট বন্ধকরণ বন্ধনীগুলির মধ্যে শ্বেতস্পেস >> বনাম>>

কোনও বিশেষায়িতকরণ বা ইনস্ট্যান্টেশনের অভ্যন্তরে >>সি ++ 03 এ পরিবর্তে ডান-শিফট হিসাবে ব্যাখ্যা করা যেতে পারে। এটি বিদ্যমান কোডটি ভাঙ্গার বেশি সম্ভাবনা রয়েছে: ( http://gustedt.wordpress.com/2013/12/15/a-disimprovement-obmitted-from-the-outside-right- Ang-- বন্ধনী / থেকে )

template< unsigned len > unsigned int fun(unsigned int x);
typedef unsigned int (*fun_t)(unsigned int);
template< fun_t f > unsigned int fon(unsigned int x);

void total(void) {
    // fon<fun<9> >(1) >> 2 in both standards
    unsigned int A = fon< fun< 9 > >(1) >>(2);
    // fon<fun<4> >(2) in C++03
    // Compile time error in C++11
    unsigned int B = fon< fun< 9 >>(1) > >(2);
}

অপারেটর newএখন বাদে অন্যান্য ব্যতিক্রম ছুঁড়ে ফেলতে পারেstd::bad_alloc

struct foo { void *operator new(size_t x){ throw std::exception(); } }
try {
    foo *f = new foo();
} catch (std::bad_alloc &) {
    // c++03 code
} catch (std::exception &) {
    // c++11 code
}

ব্যবহারকারী-ঘোষিত ডেস্ট্রাক্টরগুলির একটি অন্তর্নিহিত ব্যতিক্রমের স্পেসিফিকেশন উদাহরণ রয়েছে যা থেকে C ++ 11 এ কোন ব্রেকিং পরিবর্তন প্রবর্তিত হয়?

struct A {
    ~A() { throw "foo"; } // Calls std::terminate in C++11
};
//...
try { 
    A a; 
} catch(...) { 
    // C++03 will catch the exception
} 

size() পাত্রে এখন ও (1) এ চালানো দরকার

std::list<double> list;
// ...
size_t s = list.size(); // Might be an O(n) operation in C++03

std::ios_base::failurestd::exceptionএখন থেকে সরাসরি প্রাপ্ত হয় না

সরাসরি বেস-ক্লাসটি নতুন std::runtime_errorহলেও নয়। এভাবে:

try {
    std::cin >> variable; // exceptions enabled, and error here
} catch(std::runtime_error &) {
    std::cerr << "C++11\n";
} catch(std::ios_base::failure &) {
    std::cerr << "Pre-C++11\n";
}

11
ভাল, +1। আর একটি হ'ল একজন ব্যবহারকারী যে ডেস্ট্রাক্টর ঘোষিত হয়েছে তা এখন স্পষ্টভাবে noexecpt(true)তাই throwএকজন ডেস্ট্রাক্টরে এখন কল করবে std::terminate। তবে আমি আশা করি যে যারা এই জাতীয় কোড লিখেছেন তারা এই সম্পর্কে খুশি হবেন!
টাইপ 1232

4
তবে std :: system_error নিজেই (অপ্রত্যক্ষভাবে) std :: ব্যতিক্রম থেকে প্রাপ্ত, তাই catch (std::exception &)এখনও ধরা পড়ে std::ios_base::failure
ব্যবহারকারী 2665887

@ ব্যবহারকারী 2665887 আপনি ঠিক বলেছেন। এটি এখনও কোনও প্রোগ্রামের আচরণকে প্রভাবিত করতে পারে তবে আমি এখনই একটি ন্যূনতম উদাহরণটি ভাবতে পারি না।
উদাহরণস্বরূপ 21

4
আপনি অত্যন্ত বিভ্রান্ত, আপনি যা বলেছেন operator newতা সঠিক (এটি এখন নিক্ষেপ করতে পারে std::bad_array_new_length) তবে আপনার উদাহরণটি এটিকে মোটেই প্রদর্শন করে না। আপনি যে কোডটি দেখান সেটি সি ++ 03 এবং সি ++ 11 এএফাইক-এ একই।
মাকিং হাঁস

2
তালিকার ফ্লিপ পাশ :: আকার হ'ল ও (1) হ'ল স্প্লাইসটি এখন ও (এন)
টনি ডেল্রয়

55

আমি আপনার বাতলান এই নিবন্ধটি এবং ফলো-আপ , কীভাবে একটি চমৎকার উদাহরণ রয়েছে >>C ++ থেকে 03 সি ++ 11 অর্থ এখনও উভয় কম্পাইল পরিবর্তন করতে পারেন।

bool const one = true;
int const two = 2;
int const three = 3;

template<int> struct fun {
    typedef int two;
};

template<class T> struct fon {
    static int const three = ::three;
    static bool const one = ::one;
};

int main(void) {
    fon< fun< 1 >>::three >::two >::one; // valid for both  
}

মূল অংশটি হ'ল লাইন main, যা একটি অভিব্যক্তি।

সি ++ 03 তে:

1 >> ::three = 0
=> fon< fun< 0 >::two >::one;

fun< 0 >::two = int
=> fon< int >::one

fon< int >::one = true
=> true

সি ++ 11 এ

fun< 1 > is a type argument to fon
fon< fun<1> >::three = 3
=> 3 > ::two > ::one

::two is 2 and ::one is 1
=> 3 > 2 > 1
=> (3 > 2) > 1
=> true > 1
=> 1 > 1
=> false

অভিনন্দন, একই অভিব্যক্তির জন্য দুটি পৃথক ফলাফল। মঞ্জুর, আমি যখন এটি পরীক্ষা করেছিলাম তখন C ++ 03 একটি সতর্কতা ফর্ম কলং নিয়ে আসে।


এটা অদ্ভুত যে এটা প্রয়োজন হয় না typenameজন্য ::twoC ++ 03 সংস্করণ
জহির

3
ভাল এক, এটি বিভিন্ন স্ট্যান্ডার্ডের জন্য trueবা মূল্যায়নের জন্য ফুটে উঠছে false। হতে পারে আমরা এটিকে বৈশিষ্ট্য পরীক্ষা হিসাবে ব্যবহার করতে পারি </ জোক>
স্যামস্টার - মনিকা পুনরুদ্ধার

@ জহির, এটি কোনও ধরণের নয়, কেবল একটি মান।
ক্রিস

ঠিক আছে, যথাযথ সেমিডলাইন বিকল্পগুলি ( warning: comparisons like ‘X<=Y<=Z’ do not have their mathematical meaning [-Wparentheses]) সম্পর্কে সতর্ক করে , তবে এখনও অস্পষ্ট ::অপারেটরটির অর্থ কীভাবে পরিবর্তিত হয় তার একটি দুর্দান্ত উদাহরণ (হয় বিশ্বব্যাপী ক্ষেত্রের প্রতিচ্ছবি দেখানো বা সরাসরি তার সামনে দাঁড়িয়ে থাকা ব্যক্তিকে
উদাহরণস্বরূপ

@ উদাহরণ, আশ্চর্যজনকভাবে, জিসিসি সেই সতর্কবার্তাটি দেয়, তবে কলং তা দেয় না।
ক্রিস

39

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

1. প্রাথমিক পর্বের তালিকার মধ্যে একই ভেরিয়েবলের একাধিক রূপান্তর

একটি খুব আকর্ষণীয় কর্নারের কেস একটি প্রাথমিক সূচক তালিকার মধ্যে একই পরিবর্তনশীলটির একাধিক রূপান্তর করবে, উদাহরণস্বরূপ:

int main()
{
    int count = 0 ;
    int arrInt[2] = { count++, count++ } ;

    return 0 ;
}

C ++ 03 এবং C ++ 11 উভয় ক্ষেত্রে এটি ভালভাবে সংজ্ঞায়িত হয়েছে তবে সি ++ 03 এর মূল্যায়নের ক্রমটি অনির্ধারিত তবে সি ++ 11 এ তারা যেভাবে প্রদর্শিত হবে তার ক্রমে মূল্যায়ন করা হয় । সুতরাং আমরা যদি clangC ++ 03 মোডে ব্যবহার করে সংকলন করি তবে এটি নীচের সতর্কতা সরবরাহ করে ( এটি সরাসরি দেখুন ):

warning: multiple unsequenced modifications to 'count' [-Wunsequenced]

    int arrInt[2] = { count++, count++ } ;

                           ^        ~~

তবে সি ++ 11 এ সতর্কতা সরবরাহ করে না ( এটি সরাসরি দেখুন )।

2. নতুন সিকোয়েন্সিং বিধিগুলি i = ++ i + 1 করে; সি ++ 11 এ ভালভাবে সংজ্ঞায়িত হয়েছে

সি ++ 03 এর পরে গৃহীত নতুন সিকোয়েন্সিংয়ের অর্থ এর অর্থ:

int i = 0 ;
i = ++ i + 1;

সি ++ 11-এ আর কোনও অপরিজ্ঞাত আচরণ নেই, এটি ত্রুটি প্রতিবেদন 63৩ is- এ আচ্ছাদিত Se

৩. নতুন সিকোয়েন্সিং বিধিগুলিও ++++ i করে; সি ++ 11 এ ভালভাবে সংজ্ঞায়িত হয়েছে

সি ++ 03 এর পরে গৃহীত নতুন সিকোয়েন্সিংয়ের অর্থ এর অর্থ:

int i = 0 ;
++++i ;

সি ++ 11-এ আর কোনও পূর্বনির্ধারিত আচরণ নেই।

4. সামান্য আরও বোধগম্য বাম-শিফট স্বাক্ষরিত

সি ++ 11 এর পরে খসড়াগুলির মধ্যে অন্তর্ভুক্ত রয়েছে N3485যা আমি নীচে সংযুক্ত করছি সাইন বিটটিতে 1 বিট স্থানান্তরিত করার বা অতীত করার অপরিজ্ঞাত আচরণটি স্থির করে । এটি ত্রুটি রিপোর্টেও অন্তর্ভুক্ত রয়েছে 1457 । হাওয়ার্ড হিন্যান্ট ইজ বাম-শিফটিং (<<) সি ++ 11- তে একটি নেতিবাচক পূর্ণসংখ্যার সংশোধিত আচরণের উপর থ্রেডে এই পরিবর্তনের তাত্পর্য সম্পর্কে মন্তব্য করেছিলেন ?

5. কনটেক্সট ফাংশনগুলি সি ++ 11 এ সংকলিত সময়ের ধ্রুবক এক্সপ্রেশন হিসাবে বিবেচনা করা যেতে পারে

সি ++ 11 প্রবর্তিত কনটেক্সট ফাংশন যা:

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

যদিও সি ++ 03 তে কনস্টেক্সপ্র বৈশিষ্ট্য নেই আমাদের স্ট্যান্ডার্ড লাইব্রেরি কনস্টেক্সপ্র হিসাবে C ++ 11 তে অনেকগুলি ফাংশন সরবরাহ করে সেহেতু স্পষ্টভাবে কনসেক্সপ্রপ কীওয়ার্ডটি ব্যবহার করতে হবে না । উদাহরণস্বরূপ std :: numeric_limits :: min । যা বিভিন্ন আচরণের দিকে পরিচালিত করতে পারে, উদাহরণস্বরূপ:

#include <limits>

int main()
{
    int x[std::numeric_limits<unsigned int>::min()+2] ;
}

ব্যবহার clangC ++ 03 এই কারণ হবে xএকটি পরিবর্তনশীল দৈর্ঘ্য অ্যারে, যা হতে একটি এক্সটেনশন এবং নিম্নলিখিত সতর্কবার্তা উৎপন্ন হবে:

warning: variable length arrays are a C99 feature [-Wvla-extension]
    int x[std::numeric_limits<unsigned int>::min()+2] ;
         ^

সি ++ এ থাকা অবস্থায় std::numeric_limits<unsigned int>::min()+2একটি সংকলন সময় ধ্রুবক প্রকাশ এবং ভিএলএ এক্সটেনশনের প্রয়োজন হয় না।

C. সি ++ ১১ এ নষ্ট ব্যতিক্রমের স্পেসিফিকেশনগুলি স্পষ্টভাবে আপনার ধ্বংসকারীদের জন্য তৈরি করা হয়েছে

যেহেতু সি ++ ১১ তে ব্যবহারকারী সংজ্ঞায়িত ডেস্ট্রাক্টর নিখরচায় ডেস্ট্রাক্টরগুলিতেnoexcept(true) ব্যাখ্যা করেছেন তেমন স্পষ্ট স্পেসিফিকেশন রয়েছে যার অর্থ নিম্নলিখিত প্রোগ্রাম:

#include <iostream>
#include <stdexcept>

struct S
{
  ~S() { throw std::runtime_error(""); } // bad, but acceptable
};

int main()
{
  try { S s; }
  catch (...) {
    std::cerr << "exception occurred";
  } 
 std::cout << "success";
}

সি ++ এ কল করবে std::terminateতবে সি ++ 03 এ সফলভাবে চলবে।

7. সি ++ 03 এ টেমপ্লেট আর্গুমেন্টের অভ্যন্তরীণ লিঙ্কেজ থাকতে পারে না

এটি স্টাডি :: সাজানোর ক্ষেত্রে কোনও ফাংশনের মধ্যে ঘোষিত ক্লাসের তুলনা মেনে নেয় না কেন তা দুর্দান্তভাবে আচ্ছাদিত । সুতরাং নিম্নলিখিত কোডটি সি ++ 03 এ কাজ করা উচিত নয়:

#include <iostream>
#include <vector>
#include <algorithm>

class Comparators
{
public:
    bool operator()(int first, int second)
    {
        return first < second;
    }
};

int main()
{
    class ComparatorsInner : public Comparators{};

    std::vector<int> compares ;
    compares.push_back(20) ;
    compares.push_back(10) ;
    compares.push_back(30) ;

    ComparatorsInner comparatorInner;
    std::sort(compares.begin(), compares.end(), comparatorInner);

    std::vector<int>::iterator it;
    for(it = compares.begin(); it != compares.end(); ++it)
    {
        std::cout << (*it) << std::endl;
    }
}

কিন্তু বর্তমানে clangএকটি সতর্কবার্তা যদি না আপনি ব্যবহার সঙ্গে সি ++ 03 মোডে এই কোড পারবেন -pedantic-errorsপতাকা, কিনতে হত ধরনের যা, এটা লাইভ দেখতে পাবেন

৮. >> একাধিক টেম্পলেট বন্ধ করার সময় আর অসুস্থ হয় না

>>একাধিক টেম্পলেটগুলি বন্ধ করতে ব্যবহার করা আর অসুস্থ নয় তবে সি ++ 03 এবং সি + 11 এর বিভিন্ন ফলাফল সহ কোডে পৌঁছে দিতে পারে। নীচের উদাহরণটি ডান কোণ বন্ধনী এবং পিছনের দিকের সামঞ্জস্য থেকে নেওয়া হয়েছে :

#include <iostream>
template<int I> struct X {
  static int const c = 2;
};
template<> struct X<0> {
  typedef int c;
};
template<typename T> struct Y {
  static int const c = 3;
};
static int const c = 4;
int main() {
  std::cout << (Y<X<1> >::c >::c>::c) << '\n';
  std::cout << (Y<X< 1>>::c >::c>::c) << '\n';
}

এবং সি ++ 03 এর ফলাফল হ'ল:

0
3

এবং সি ++ 11 এ:

0
0

9. সি ++ 11 স্ট্যান্ড :: ভেক্টর কনস্ট্রাক্টরগুলির মধ্যে কিছু পরিবর্তন করে

এই উত্তর থেকে কিছুটা সংশোধিত কোড দেখায় যে নিম্নলিখিত স্ট্যান্ডার্ড :: ভেক্টর থেকে নির্মাণকারীর ব্যবহার :

std::vector<T> test(1);

সি ++ 03 এবং সি ++ 11 এ বিভিন্ন ফলাফল উত্পাদন করে:

#include <iostream>
#include <vector>

struct T
{
    bool flag;
    T() : flag(false) {}
    T(const T&) : flag(true) {}
};


int main()
{
    std::vector<T> test(1);
    bool is_cpp11 = !test[0].flag;

    std::cout << is_cpp11 << std::endl ;
}

10. সামগ্রিক প্রারম্ভিকগুলিতে সংকীর্ণ রূপান্তর

সি ++ ১১-তে সামগ্রিক প্রারম্ভিকদের মধ্যে সংকীর্ণ রূপান্তরটি দুর্গঠিত এবং দেখে মনে হচ্ছে এটি gccসি ++ 11 এবং সি ++ 03 উভয় ক্ষেত্রেই অনুমতি দেয় যদিও এটি সি ++ 11 এ ডিফল্টরূপে একটি সতর্কতা প্রদান করে:

int x[] = { 2.0 };

এটি খসড়া সি ++ 11 স্ট্যান্ডার্ড বিভাগের 8.5.4 তালিকা-সূচনা অনুচ্ছেদ 3 এ আচ্ছাদিত রয়েছে :

টি-এর একটি অবজেক্টের রেফারেন্স-ইনিশায়ালাইজেশন বা রেফারেন্স নীচে সংজ্ঞায়িত করা হয়েছে:

এবং নিম্নলিখিত বুলেট রয়েছে ( জোর দেওয়া খনি ):

অন্যথায়, টি যদি শ্রেণীর ধরণের হয় তবে নির্মাতারা বিবেচনা করা হয়। প্রযোজ্য কন্সট্রাক্টরগুলি গণনা করা হয় এবং ওভারলোড রেজোলিউশনের (13.3, 13.3.1.7) মাধ্যমে সেরাটি বেছে নেওয়া হয়। যদি কোনও সংকীর্ণ রূপান্তর (নীচে দেখুন) কোনও আর্গুমেন্ট রূপান্তর করতে প্রয়োজন হয়, প্রোগ্রামটি দুর্গঠিত

এটি এবং আরও অনেক উদাহরণ সি ++ স্ট্যান্ডার্ড বিভাগ annex C.2 সি ++ এবং আইএসও সি ++ 2003 খসড়াতে আচ্ছাদিত । এর মধ্যে রয়েছে:

  • নতুন ধরণের স্ট্রিং লিটারাল [...] বিশেষত, স্ট্রিং আক্ষরিক সংলগ্ন যখন আর, ইউ 8, ইউ 8 আর, ইউ, ইউআর, ইউ, ইউআর, বা এলআর নামের ম্যাক্রোগুলি প্রসারিত হবে না তবে স্ট্রিং আক্ষরিক অংশ হিসাবে ব্যাখ্যা করা হবে । উদাহরণ স্বরূপ

    #define u8 "abc"
    const char *s = u8"def"; // Previously "abcdef", now "def"
  • ব্যবহারকারী-সংজ্ঞায়িত আক্ষরিক স্ট্রিং সমর্থন [...] পূর্বে, # 1 এ দুটি পৃথক প্রিপ্রোসেসিং টোকেন এবং ম্যাক্রো _ এক্স প্রসারিত হত। এই আন্তর্জাতিক স্ট্যান্ডার্ডে, # 1 টিতে একটি একক প্রিপ্রোসেসিং টোকেন থাকে, সুতরাং ম্যাক্রো প্রসারিত হয় না।

    #define _x "there"
    "hello"_x // #1
  • পূর্ণসংখ্যার / এবং% [...] 2003 কোডের ফলাফলের জন্য রাউন্ডিং নির্দিষ্ট করুন যা সংখ্যার বিভাগের ব্যবহার করে 0 টি বা নেতিবাচক অসীমের দিকে গোল করে, যখন এই আন্তর্জাতিক স্ট্যান্ডার্ড সর্বদা ফলাফলকে 0 এর দিকে গোল করে।

  • আকারের জটিলতা () সদস্যের ফাংশনগুলি এখন ধ্রুবক [...] সি ++ 2003 অনুসারে কিছু ধারক বাস্তবায়ন এই আন্তর্জাতিক স্ট্যান্ডার্ডের নির্দিষ্ট আকার () প্রয়োজনীয়তার সাথে সঙ্গতিপূর্ণ নাও হতে পারে। স্ট্র্যাটার প্রয়োজনীয়তার সাথে স্ট্যান্ড :: তালিকার মতো পাত্রে সামঞ্জস্য করার ক্ষেত্রে বেমানান পরিবর্তনগুলির প্রয়োজন হতে পারে।

  • Std :: ios_base :: এর ব্যাস ক্লাস পরিবর্তন করুন ব্যর্থতা [...] std :: ios_base :: ব্যর্থতা আর সরাসরি স্ট্যান্ড :: ব্যতিক্রম থেকে প্রাপ্ত নয়, তবে এখন std :: system_error থেকে উদ্ভূত, যা পরিবর্তিতভাবে থেকে প্রাপ্ত এসটিডি :: runtime_error। বৈধ সি ++ 2003 কোড যা ধরে নিয়েছে যে এইচটিডি: আইওএস_বেস :: ব্যর্থতা সরাসরি এসটিডি থেকে উদ্ভূত হয়েছে :: ব্যতিক্রমটি এই আন্তর্জাতিক স্ট্যান্ডার্ডে ভিন্নভাবে কার্যকর করতে পারে।


সুতরাং বেশিরভাগ উদাহরণ সংকীর্ণ হয়ে যায় যে পূর্বে অপরিবর্তিত আচরণটি এখন ভালভাবে সংজ্ঞায়িত হয়েছে?
ম্যাথিয়াসবি

@ মাথিয়াসবি 2, 3 এবং 4 এটি সম্পর্কে তাই এই মুহুর্তে তারা আর উদাহরণগুলির সংখ্যাগরিষ্ঠ নয়। আমি সন্দেহ করি আমি আরও অনেক অপরিজ্ঞাত আচরণের উদাহরণগুলি খুঁজে পাব যাতে আমি আরও যুক্ত করার সাথে সাথে তারা একটি ছোট সেট হয়ে যাবে।
শফিক ইয়াঘমুর

ঠিক আছে, # 1 আচরণটি অনির্ধারিত, সুতরাং আমি এটিকে অপরিজ্ঞাত আচরণ হিসাবে গণ্য করব (কমপক্ষে আপনি সি ++ 03 দিয়ে সুনির্দিষ্ট ফলাফল পাওয়ার আশা করতে পারবেন না, এখন আপনি সি ++ 11 দিয়ে পারেন), # 5 একটি অ- সি ++ এর স্ট্যান্ডার্ড এক্সটেনশন। তবে আমার ধারণা আপনি ঠিক বলেছেন আপনি এটির জন্য যত বেশি সন্ধান করেন, তত বেশি উদাহরণ আপনি খুঁজে পাবেন যা উভয় মানের মধ্যে সংজ্ঞায়িত হলেও বিভিন্ন ফলাফল প্রকাশ করে।
ম্যাথিয়াসবি

@ মাথিয়াসবি হ্যাঁ, উভয় অনির্দিষ্ট ও অপরিজ্ঞাত আচরণের অনাকাঙ্ক্ষিত ফলাফল রয়েছে। লিনাক্স বিবেচনা করে এক্সটেনশনের ক্ষেত্রে, বেশিরভাগ জিসিসি এক্সটেনশনের উপর নির্ভর করে আমাদের তাদের আসল বিশ্বে ধারণা করা উচিত। আমি যখন প্রথম এই প্রশ্নের উত্তর দিয়েছিলাম তখন আমি এতগুলি উদাহরণ পাওয়ার আশা করি না।
শফিক ইয়াঘমুর

35

একটি সম্ভাব্য বিপজ্জনক পশ্চাৎ-অসামঞ্জস্যপূর্ণ পরিবর্তন হ'ল সিক্যুয়েন্স পাত্রে যেমন std::vectorবিশেষত ওভারলোডে প্রাথমিক আকারের নির্দিষ্টকরণের নির্মাতারা in যেখানে C ++ 03 তে তারা ডিফল্ট-নির্মিত উপাদানগুলি অনুলিপি করেছে, সি ++ 11 এ তারা প্রত্যেকে ডিফল্ট-নির্মাণ করে।

এই উদাহরণটি বিবেচনা করুন ( boost::shared_ptrযাতে এটি কার্যকর বৈধ C ++ 03):

#include <deque>
#include <iostream>

#include "boost/shared_ptr.hpp"


struct Widget
{
  boost::shared_ptr<int> p;

  Widget() : p(new int(42)) {}
};


int main()
{
  std::deque<Widget> d(10);
  for (size_t i = 0; i < d.size(); ++i)
    std::cout << "d[" << i << "] : " << d[i].p.use_count() << '\n';
}

সি ++ 03 লাইভ উদাহরণ

সি ++ 11 লাইভ উদাহরণ

কারণটি হ'ল সি ++ 03 "মাপ এবং প্রোটোটাইপ উপাদান নির্দিষ্ট করুন" এবং "কেবলমাত্র আকার নির্দিষ্ট করুন" উভয়ের জন্য একটি ওভারলোড নির্দিষ্ট করে (ব্রেবিটির জন্য বাদ দেওয়া যুক্তি যুক্তি):

container(size_type size, const value_type &prototype = value_type());

এটি সবসময় prototypeধারক sizeসময়ের মধ্যে অনুলিপি করা হবে । যখন কেবল একটি যুক্তি দিয়ে ডাকা হয়, সুতরাং এটি sizeডিফল্ট-নির্মিত নির্মিত উপাদানটির অনুলিপি তৈরি করে।

সি ++ 11 এ, এই নির্মাণকারীর স্বাক্ষরটি সরানো হয়েছিল এবং এই দুটি ওভারলোডের সাথে প্রতিস্থাপন করা হয়েছে:

container(size_type size);

container(size_type size, const value_type &prototype);

দ্বিতীয়টি উপাদানটির sizeঅনুলিপি তৈরি করে আগের মতো কাজ করে prototype। তবে, প্রথমটি (যা এখন কেবলমাত্র আকারের যুক্তির সাহায্যে কলগুলি পরিচালনা করে) ডিফল্ট প্রতিটি উপাদান পৃথকভাবে তৈরি করে।

এই পরিবর্তনের কারণ হিসাবে আমার ধারণা হ'ল কেবলমাত্র সরানো উপাদান ধরণের সাথে C ++ 03 ওভারলোড ব্যবহারযোগ্য হবে না। তবে এটি একটি ব্রেকিং পরিবর্তন কম, এবং একটি খুব কমই এটিতে নথিভুক্ত।


3
যদিও এটি স্পষ্টতই একটি ব্রেকিং পরিবর্তন, আমি সি ++ 11 আচরণ পছন্দ করি। আমি আশা করব এটির ফলাফল dequeহোল্ডিংয়ের জন্য দশটি আলাদা উইজেট হবে, দশটি উইজেট একই সংস্থানটি ভাগ করে নেবে না।
এজেন্টলিয়ান

19

একটি থেকে ব্যর্থ পঠনের ফলাফল std::istreamপরিবর্তিত হয়েছে। সি পি সি রেফারেন্স এটিকে সুন্দরভাবে সংক্ষিপ্তসার করে:

নিষ্কাশন ব্যর্থ হলে (উদাহরণস্বরূপ যদি কোনও চিঠি প্রবেশ করানো হয় যেখানে একটি অঙ্ক প্রত্যাশিত হয়), valueঅবিস্মরণীয় রেখে দেওয়া হয় এবং failbitসেট করা থাকে। (সি ++ 11 অবধি)

নিষ্কাশন ব্যর্থ হলে শূন্যটি লিখিত হয় valueএবং failbitসেট করা থাকে। মান অত্যন্ত বড় বা খুব ছোট নিষ্কাশন ফলাফলে মাপসই তাহলে value, std::numeric_limits<T>::max()বা std::numeric_limits<T>::min()লেখা আছে এবং failbitপতাকা সেট করা হয়। (যেহেতু সি ++ ১১)

এটি প্রাথমিকভাবে একটি ইস্যু যদি আপনি নতুন শব্দার্থবিজ্ঞানে অভ্যস্ত হন এবং তারপরে সি ++ 03 ব্যবহার করে লিখতে হয়। নিম্নলিখিতটি বিশেষত ভাল অনুশীলন নয় তবে সি ++ 11 এ ভালভাবে সংজ্ঞায়িত হয়েছে:

int x, y;
std::cin >> x >> y;
std::cout << x + y;

যাইহোক, সি ++ 03 তে উপরের কোডটি একটি অবিচ্ছিন্ন ভেরিয়েবল ব্যবহার করে এবং এর ফলে অপরিবর্তিত আচরণ রয়েছে।


4
আপনি যোগ করতে পারেন, যে সি ++ 03 এ কেউ মান হিসাবে এই মান ব্যবহার করা যেতে পারে একটি ডিফল্ট মান প্রদান করতে int x = 1, y = 1; cin >> x >> y; cout << x*y;। C ++ 03 দিয়ে, xযখন সঠিকভাবে yপড়া যায় না তখন এটি সঠিকভাবে উত্পাদন করতে পারে।
--মাস্টার

15

এই থ্রেডটি রান-টাইমে C ++ 03 এবং C ++ 0x এর মধ্যে কি পার্থক্যগুলি সনাক্ত করতে পারে , ভাষা পার্থক্য নির্ধারণের জন্য উদাহরণ রয়েছে (সেই থ্রেড থেকে অনুলিপি করা হয়েছে), উদাহরণস্বরূপ C ++ 11 রেফারেন্সকে ভেঙে ফেলা দ্বারা:

template <class T> bool f(T&) {return true; } 
template <class T> bool f(...){return false;} 

bool isCpp11() 
{
    int v = 1;
    return f<int&>(v); 
}

এবং সি ++ 11 স্থানীয় প্রকারকে টেম্পলেট প্যারামিটার হিসাবে অনুমতি দেয়:

template <class T> bool cpp11(T)  {return true;} //T cannot be a local type in C++03
                   bool cpp11(...){return false;}

bool isCpp0x() 
{
   struct local {} var; //variable with local type
   return cpp11(var);
}

7

এখানে অন্য একটি উদাহরণ:

#include <iostream>

template<class T>
struct has {
  typedef char yes;
  typedef yes (&no)[2];    
  template<int> struct foo;    
  template<class U> static yes test(foo<U::bar>*);      
  template<class U> static no  test(...);    
  static bool const value = sizeof(test<T>(0)) == sizeof(yes);
};

enum foo { bar };

int main()
{
    std::cout << (has<foo>::value ? "yes" : "no") << std::endl;
}

ছাপে:

Using c++03: no
Using c++11: yes

কলিরুতে ফলাফল দেখুন

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