রান-টাইমে সি ++ 03 এবং সি ++ 11 এর মধ্যে কী পার্থক্য রয়েছে?


116

কোনও ফাংশন লেখা সম্ভব, যা সি সংকলক দিয়ে সংকলিত হলে 0 ফিরে আসবে, এবং যখন সি ++ সংকলকটি সংকলিত হবে তখন 1 ফিরে আসবে (এর সাথে তুচ্ছ স্লিউশন #ifdef __cplusplusআকর্ষণীয় নয়)।

উদাহরণ স্বরূপ:

int isCPP()
{
    return sizeof(char) == sizeof 'c';
}

অবশ্যই, উপরেরগুলি কেবল তখনই কাজ করবে যদি sizeof (char)সেটির মতো না হয়sizeof (int)

আরেকটি, আরও বহনযোগ্য সমাধান হ'ল এরকম কিছু:

int isCPP()
{
    typedef int T;
    {
       struct T 
       {
           int a[2];
       };
       return sizeof(T) == sizeof(struct T);
    }
}

উদাহরণগুলি 100% সঠিক কিনা তা আমি নিশ্চিত নই, তবে আপনি ধারণাটি পাবেন। আমি বিশ্বাস করি একই ফাংশনটি লেখার অন্যান্য উপায়ও রয়েছে।

রান-টাইমে সি ++ 03 এবং সি ++ 11 এর মধ্যে কোন পার্থক্য রয়েছে? অন্য কথায়, এটি কি একইরকম ফাংশন লেখা সম্ভব যা একটি বুলিয়ান মান প্রদান করবে যেটি বোঝায় যে এটি একটি সংগত সি ++ 03 সংকলক বা সি ++ 11 সংকলক দ্বারা সংকলিত হয়েছে কিনা?

bool isCpp11()
{ 
    //???
} 

10
এবং এই মহড়ার মূল বিষয় কী? প্রথমত, আপনার কাছে ম্যাক্রো রয়েছে এবং দ্বিতীয়ত, সংকলকগণ সি ++ 0 এক্স এর সমস্ত বৈশিষ্ট্য প্রয়োগ করতে শুরু করার আগে বেশ কয়েক বছর সময় নেবে, এর মধ্যে এটি মিশ্রণ হবে। সুতরাং একমাত্র যুক্তিসঙ্গত পরীক্ষাটি হ'ল সংস্করণ ম্যাক্রো সংকলক।
জিন বুশুয়েভ

4
এটি আসল প্রশ্ন নয় বরং বিলের সাথে মানিয়ে যায় তবে নিয়মগুলি মেনে চলা খুব আকর্ষণীয় বলে মনে হয়!
ডেভিড হেফারনান

4
@ জেন এট আল: আপনি কি এমন সব প্রশ্নকে কমিয়ে দিয়েছেন যা আকর্ষণীয় তবে আপনি ব্যবহারিক "পয়েন্ট" দেখছেন না?
আর্মেন ​​সিরুনিয়ান

2
"আমরা সাধারণত প্রত্যাশা, তথ্যসূত্র বা নির্দিষ্ট দক্ষতার সাথে জড়িত উত্তরগুলি আশা করি"। আমি মনে করি এই প্রশ্নটি এই প্রত্যাশা পূরণ করে, পুনরায় জন্য ভোট দিন।
কারেল পেট্রেনেক

6
@ সিকসলেটটারে পরিবর্তনগুলি: যদিও এটি যুক্তির পক্ষে অবশ্যই উন্মুক্ত যে ফ্রেসিংটি আরও ভাল হতে পারে, তবে আমার কাছে মনে হয় যে প্রশ্নের মূল ধারণাটি (সি ++ 03 এবং সি ++ 0x এর মধ্যে কোন পার্থক্য, যদি কোনটিই সনাক্ত করা যায় তবে- সময়?) পুরোপুরি বৈধ। কোডটি উভয়কেই সংকলন ও সম্পাদন করতে হবে, এটি সি ++ 0 এক্সের ব্রেকিং পরিবর্তন সম্পর্কেও চিহ্নিত করা যেতে পারে। এটি আমার কাছে পুরোপুরি বৈধ প্রশ্নের মতো জিজ্ঞাসা করার মতো বলে মনে হয়।
জেরি কফিন

উত্তর:


108

মূল ভাষা

এটি ব্যবহার করে একটি গণক অ্যাক্সেস করা হচ্ছে :::

template<int> struct int_ { };

template<typename T> bool isCpp0xImpl(int_<T::X>*) { return true; }
template<typename T> bool isCpp0xImpl(...) { return false; }

enum A { X };
bool isCpp0x() {
  return isCpp0xImpl<A>(0);
}

আপনি নতুন কীওয়ার্ডগুলি অপব্যবহার করতে পারেন

struct a { };
struct b { a a1, a2; };

struct c : a {
  static b constexpr (a());
};

bool isCpp0x() {
  return (sizeof c::a()) == sizeof(b);
}

এছাড়াও, স্ট্রিং লিটারালগুলি আর রূপান্তর করে না char*

bool isCpp0xImpl(...) { return true; }
bool isCpp0xImpl(char*) { return false; }

bool isCpp0x() { return isCpp0xImpl(""); }

যদিও বাস্তব বাস্তবায়নে আপনার এই কাজটি হওয়ার সম্ভাবনা রয়েছে তা আমি জানি না। এক যে শোষণ করেauto

struct x { x(int z = 0):z(z) { } int z; } y(1);

bool isCpp0x() {
  auto x(y);
  return (y.z == 1);
}

নিম্নলিখিতটি সি -+ 0 এক্সে operator int&&রূপান্তর ফাংশন int&&এবং intলজিক্যাল-এবং সি ++ 03 এর পরে রূপান্তরিত ফাংশনের উপর ভিত্তি করে রয়েছে

struct Y { bool x1, x2; };

struct A {
  operator int();
  template<typename T> operator T();
  bool operator+();
} a;

Y operator+(bool, A);

bool isCpp0x() {
  return sizeof(&A::operator int&& +a) == sizeof(Y);
}

সেই পরীক্ষার কেসটি জিসিসিতে সি ++ 0x এর জন্য কাজ করে না (বাগের মতো দেখায়) এবং ঝাঁকুনির জন্য সি ++ 03 মোডে কাজ করে না। একটি ঝনঝন জনসংযোগ দায়ের করা হয়েছে

ইনজেকশনের বর্গ নামের পরিবর্তিত চিকিত্সা সি ++ 11 টেমপ্লেট:

template<typename T>
bool g(long) { return false; }

template<template<typename> class>
bool g(int) { return true; }

template<typename T>
struct A {
  static bool doIt() {
    return g<A>(0);
  }
};

bool isCpp0x() {
  return A<void>::doIt();
}

"এটি সি ++ 03 বা সি ++ 0x কিনা" সনাক্ত করে একটি দম্পতি বিরতি পরিবর্তনগুলি প্রদর্শন করতে ব্যবহার করা যেতে পারে। নীচে একটি টুইটযুক্ত টেস্টকেস রয়েছে, যা প্রাথমিকভাবে এই জাতীয় পরিবর্তন দেখাতে ব্যবহৃত হয়েছিল, কিন্তু এখন সি ++ 0 এক্স বা সি ++ 03 এর জন্য পরীক্ষার জন্য ব্যবহৃত হয়।

struct X { };
struct Y { X x1, x2; };

struct A { static X B(int); };
typedef A B;

struct C : A {
  using ::B::B; // (inheriting constructor in c++0x)
  static Y B(...);
};

bool isCpp0x() { return (sizeof C::B(0)) == sizeof(Y); }

স্ট্যান্ডার্ড লাইব্রেরি

operator void*সি ++ 0x 'এর অভাব সনাক্তকরণstd::basic_ios

struct E { E(std::ostream &) { } };

template<typename T>
bool isCpp0xImpl(E, T) { return true; }
bool isCpp0xImpl(void*, int) { return false; }

bool isCpp0x() {
  return isCpp0xImpl(std::cout, 0);
}

1
খুশী হলাম। আমি নিশ্চিত করতে পারি যে এই দ্রষ্টব্যটি -std = c ++ 0x এর সাথে এবং ছাড়া উভয়ই g ++ (GCC) 4.6.0 নিয়ে কাজ করে।
আলেকজান্ডার

2
এই আয় trueMSVC 2005 অগ্রে জন্য, এবং MSVC 2003 সালে একটি কম্পাইল ত্রুটি
এন্থনি উইলিয়ামস

1
ওহে প্রিয়, তারা পিছনে সামঞ্জস্য ভেঙে!
অবাকর

14
@ জোহানেস: আপনি সপ্তাহে সবচেয়ে মজা পেয়েছেন, তাই না? ; -]
iljarn

4
আমি এগুলিকে খুব আকর্ষণীয় মনে করি তবে আমি মনে করি সবচেয়ে চালাক (...)বনাম (char*)কল the আমি সত্যিই যে পছন্দ!
কর্সিকা

44

আমি একটি অনুপ্রেরণা পেয়েছি সি ++ 11 এ কি ব্রেকিং পরিবর্তনগুলি চালু করা হয়েছে? :

#define u8 "abc"

bool isCpp0x() {
   const std::string s = u8"def"; // Previously "abcdef", now "def"
   return s == "def";
}

এটি ম্যাক্রো প্রসারণের চেয়ে অগ্রাধিকার প্রাপ্ত নতুন স্ট্রিং লিটারেলের উপর ভিত্তি করে।


1
+1: অত্যন্ত আকর্ষণীয়, প্রকৃতপক্ষে, তবে প্রযুক্তিগতভাবে প্রিপ্রসেসর ব্যবহার না করার প্রয়োজনীয়তা ভঙ্গ করে। তবে এই নিষেধাজ্ঞার এত সুন্দর উত্তর খারিজ করার উদ্দেশ্য ছিল না :)
আরমান সিরুনিয়ান

1
ঠিক আছে, আপনি যদি ফাংশনটি একটি দিয়ে অনুসরণ করেন #undef u8তবে প্রিপ্রসেসর ব্যবহার কেবল তখনই পর্যবেক্ষণযোগ্য যদি আপনার প্রোগ্রামটিতে পূর্বে-সংজ্ঞায়িত ম্যাক্রো u8(বুও) থাকে। যদি এটি সত্যিকারের উদ্বেগ হয় তবে তা এখনও বাস্তবায়ন-নির্দিষ্ট ধাক্কা / পপ ম্যাক্রো প্রগমাস / কলগুলি ব্যবহার করে কাজ করা যেতে পারে (বেশিরভাগ বাস্তবায়নে এগুলি রয়েছে, আমি বিশ্বাস করি)।
জেমস ম্যাকনেলিস

3
একটি মোটামুটি যুক্তিযুক্ত যুক্তি হ'ল সি ++ 03 সিস্টেমে কেউ সিমুলেটেড সি ++ 0 এক্স ক্ষমতা সরবরাহ করতে u8 নির্ধারণ করতে পারে। তবুও, আমি উত্তরটি সত্যিই পছন্দ করি।
ক্রিস্টোফার স্মিথ

1
আপনি কেবল এই ইস্পিপেক্স এক্স ফাংশনটিকে একটি পৃথক অনুবাদ ইউনিটে স্থানান্তর করতে পারেন যাতে এই ম্যাক্রো জিনিসটি অন্য কোডকে প্রভাবিত করে না।
আনকুলঙ্কুলু

1
আমি মনে করি কিছু ম্যাক্রো মান নির্ধারণকারী সংকলকটির উপর নির্ভর করার জন্য প্রিপ্রসেসর ব্যবহার করে এবং প্রকৃত ভাষার বৈশিষ্ট্যগুলি সনাক্ত করতে প্রিপ্রসেসর ব্যবহার করে a এই কারণেই আমি মনে করি না যে এই উত্তরটি প্রতারণা করছে।
অরবিটে লাইটনেস রেস

33

>>টেমপ্লেটগুলি বন্ধ করার জন্য নতুন নিয়ম ব্যবহার করে একটি চেক সম্পর্কে কীভাবে :

#include <iostream>

const unsigned reallyIsCpp0x=1;
const unsigned isNotCpp0x=0;

template<unsigned>
struct isCpp0xImpl2
{
    typedef unsigned isNotCpp0x;
};

template<typename>
struct isCpp0xImpl
{
    static unsigned const reallyIsCpp0x=0x8000;
    static unsigned const isNotCpp0x=0;
};

bool isCpp0x() {
    unsigned const dummy=0x8000;
    return isCpp0xImpl<isCpp0xImpl2<dummy>>::reallyIsCpp0x > ::isNotCpp0x>::isNotCpp0x;
}

int main()
{
    std::cout<<isCpp0x()<<std::endl;
}

বিকল্পভাবে এর জন্য দ্রুত চেক করুন std::move:

struct any
{
    template<typename T>
    any(T const&)
    {}
};

int move(any)
{
    return 42;
}

bool is_int(int const&)
{
    return true;
}

bool is_int(any)
{
    return false;
}


bool isCpp0x() {
    std::vector<int> v;
    return !is_int(move(v));
}

6
+1 একটি দুর্দান্ত ধারণা :) তবে বাস্তবে এটি ভিজ্যুয়াল সি ++ 2005/2088 এর সাথে ভেঙে যাবে যা সি ++ 0x সমর্থন করে না >> তবে সি ++ 0x উপায়ে টেমপ্লেটগুলিতে ব্যবহার করার অনুমতি দেয়।
কারেল পেট্রেনেক

4
Oooh; আমি ADL আপত্তি পছন্দ! যাইহোক, মানানসই C ++ 03 বাস্তবায়নের নামকরণ কোনও ফাংশন থাকতে পারে না std::move?
জেমস ম্যাকনেলিস

1
@ ফ্রেড ওভারফ্লো: আমি বিরক্ত করব না। ইউআই চুষে!
হালকা ঘোড়দৌড়

16

পূর্ববর্তী সি ++ থেকে পৃথক, সি ++ 0x রেফারেন্স প্রকারগুলি থেকে রেফারেন্স প্রকারগুলি তৈরি করতে অনুমতি দেয় যদি সেই বেস রেফারেন্স টাইপের মাধ্যমে প্রবর্তন করা হয়, উদাহরণস্বরূপ, একটি টেম্পলেট প্যারামিটার:

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

bool isCpp0x() 
{
    int v = 1;
    return func<int&>(v); 
}

দুর্ভাগ্যক্রমে, পিছনে সামঞ্জস্যতা ভাঙার দামে নিখুঁত ফরওয়ার্ডিং আসে।

আর-পরীক্ষাটি এখন-অনুমোদিত স্থানীয় ধরণের উপর ভিত্তি করে টেমপ্লেট আর্গুমেন্ট হিসাবে থাকতে পারে:

template <class T> bool cpp0X(T)  {return true;} //cannot be called with local types in C++03
                   bool cpp0X(...){return false;}

bool isCpp0x() 
{
   struct local {} var;
   return cpp0X(var);
}

সম্ভবত আমার
এটিকে

1
+1 দুর্দান্ত ধারণা, আমি কেবলমাত্র isC++0xবৈধ সি ++ সনাক্তকারী কিনা তা নিশ্চিত নই ;)
কারেল পেট্রেনেক

1
উল্লেখ রেফারেন্স থেকে রেফারেন্স জন্য ভাল রেফারেন্স কি?
কেরেক এসবি

@ kerrek-SB: 8.3.2.6 (রেফারেন্সেস) এই সম্পর্কে খসড়া আলোচনা
uwedolinsky

15

এটি বেশ সঠিক উদাহরণ নয়, তবে এটি একটি আকর্ষণীয় উদাহরণ যা সি বনাম সি ++ 0x পার্থক্য করতে পারে (এটি অবৈধ সি ++ 03):

 int IsCxx03()
 {
   auto x = (int *)0;
   return ((int)(x+1) != 1);
}

10
প্রযুক্তিগতভাবে, এটি sizeof(int) != 1সত্য হওয়ার উপর নির্ভর করে । ব্যতিক্রমী বড় charগুলি সহ 0 এক্স সিস্টেমে ফলাফলগুলি একই হতে পারে। এখনও একটি ঝরঝরে কৌশল।
ডেনিস জিকিফুজ

@ ডেনিস - charসর্বদা যদিও একটি বাইট
নোড

4
@ নোড: একটি বাইট সবসময় 8 বিট হয় না।
আলেকজান্দ্রি সি

2
sizeof(char)সংজ্ঞা অনুসারে @ নোড সর্বদা 1 হবে তবে CHAR_BIT(সীমাবদ্ধতাগুলিতে সংজ্ঞায়িত) 8 এর বেশি হওয়ার অনুমতি দেওয়া হয়েছে ফলস্বরূপ, উভয় charএবং int32 বিট থাকতে পারে, যার ক্ষেত্রে sizeof(int) == 1(এবং CHAR_BIT == 32)।
সুজোরড

12

এই প্রশ্ন থেকে :

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

std::vector<T> test(1);
bool is_cpp0x = !test[0].flag;

আমি ভাবলাম কীভাবে এটি কাজ করতে পারে; এটি চেষ্টা করার পরে, এটি এখন স্পষ্ট: একটি ছোট বাগ আছে। এটি কাজ করে যদি আপনি শেষ লাইনটি পরিবর্তন করুন:bool is_cpp0x = !test[0].flag;
awx

1
প্লাজেবল: সি ++ 0 এক্স ডিফল্ট কনস্ট্রাক্টস Tযেখানে সি ++ 03 অনুলিপি থেকে তৈরি করা হয়েছেT()
অ্যাওএক্স

9

এতটা সংক্ষিপ্ত না হলেও ... বর্তমান সি ++ তে শ্রেণি টেম্পলেটটির নামটি শ্রেণীর টেম্পলেটটির স্কোপগুলিতে একটি টাইপের নাম (কোনও টেম্পলেট নাম নয়) হিসাবে ব্যাখ্যা করা হয়। অন্যদিকে, শ্রেণি টেম্পলেট নামটি টেম্পলেটটির নাম হিসাবে C ++ 0x (N3290 14.6.1 / 1) হিসাবে ব্যবহার করা যেতে পারে।

template< template< class > class > char f( int );
template< class > char (&f(...))[2];

template< class > class A {
  char i[ sizeof f< A >(0) ];
};

bool isCpp0x() {
  return sizeof( A<int> ) == 1;
}

9
#include <utility>

template<typename T> void test(T t) { t.first = false; }

bool isCpp0x()
{
   bool b = true;
   test( std::make_pair<bool&>(b, 0) );
   return b;
}

এনবি প্রযুক্তিগতভাবে এটি স্ট্যান্ডার্ড লাইব্রেরিটি সংকলক নয়, পরীক্ষা করে এবং এটি বৈধ সি ++ 03 এবং বৈধ সি ++ 0x হলেও এটি বৈধ সি ++ 98 নয়, সুতরাং কিছু টুইটের সাহায্যে একটি সি ++ 98 / সনাক্ত করা যায় সি ++ 03 / সি ++ 0x স্টেডলিব
জোনাথন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.