ব্যবহারকারী-সংজ্ঞায়িত আক্ষরিকাগুলি সি ++ এ কী নতুন ক্ষমতা যুক্ত করে?


139

সি ++ 11 প্রবর্তন ব্যবহারকারী-সংজ্ঞায়িত লিটারেল যা বিদ্যমান লিটারেল উপর ভিত্তি করে নতুন আক্ষরিক সিনট্যাক্স প্রবর্তনের অনুমতি দেবে ( int, hex, string, float) যাতে কোনো ধরনের একটি আক্ষরিক উপস্থাপনা আছে সক্ষম হতে হবে।

উদাহরণ:

// imaginary numbers
std::complex<long double> operator "" _i(long double d) // cooked form
{ 
    return std::complex<long double>(0, d); 
}
auto val = 3.14_i; // val = complex<long double>(0, 3.14)

// binary values
int operator "" _B(const char*); // raw form
int answer = 101010_B; // answer = 42

// std::string
std::string operator "" _s(const char* str, size_t /*length*/) 
{ 
    return std::string(str); 
}

auto hi = "hello"_s + " world"; // + works, "hello"_s is a string not a pointer

// units
assert(1_kg == 2.2_lb); // give or take 0.00462262 pounds

প্রথম নজরে এটি খুব দুর্দান্ত দেখায় তবে আমি ভাবছিলাম যে এটি সত্যিই কতটা প্রযোজ্য, যখন আমি প্রত্যয় থাকার কথা চিন্তা করার চেষ্টা করেছি _ADএবং _BCতারিখগুলি তৈরি করার সময় আমি খুঁজে পেলাম যে এটি অপারেটরের আদেশের কারণে সমস্যাযুক্ত। 1974/01/06_ADপ্রথমে মূল্যায়ন 1974/01(প্লেইন intগুলি হিসাবে ) এবং কেবলমাত্র পরে 06_AD(অগস্ট এবং সেপ্টেম্বরের কিছুই 0অষ্টাল কারণে না লিখতে হবে )। সিনট্যাক্সটি তৈরি করে এটি প্রায় কাজ করা যেতে পারে 1974-1/6_ADযাতে অপারেটর মূল্যায়নের আদেশ কাজ করে তবে এটি জটিল।

সুতরাং আমার প্রশ্নটি যা এটিকে ফুটিয়ে তোলে, আপনি কি মনে করেন এই বৈশিষ্ট্যটি ন্যায্যতা পাবে? আপনি অন্য কোন আক্ষরিক সংজ্ঞা দিতে চান যা আপনার সি ++ কোডটি আরও পঠনযোগ্য করে তুলবে?


জুন ২০১১ এ চূড়ান্ত খসড়াটি ফিট করতে সিনট্যাক্স আপডেট হয়েছে


8
আমি এটি বন্ধ করতে ভোট দিতে হবে। শিরোনামটি বেশ স্পষ্টভাবে ইনফ্ল্যামেটরি।
পপি

76
@ ডেড এমজি, শিরোনামের বুদ্ধিমান যদি আপনার কোন সমস্যা থাকে তবে আপনি এটি সম্পাদনা করতে পারেন। এটি 11 টি upvotes এবং 8 টি পছন্দসই 3 বছরের পুরানো প্রশ্নটি বন্ধ করার চেষ্টা করা কিছুটা মজাদার। (এই সাইটের শিষ্টাচার গত 3 বছরে পরিবর্তিত হয়েছে তা উল্লেখ নয়)।
মোটি

5
আমি মনে করি আপনার উদাহরণগুলিতে আপনার একটি ত্রুটি রয়েছে: string operator "" _s(const char*s);"পার্স করার জন্য ব্যবহার করা যাবে না "hello"_s"। এটি একটি স্ট্রিং আক্ষরিক এবং অতিরিক্ত size_tপ্যারামিটার সহ অপারেটরের সন্ধান করবে । আমি কি সঠিক?
তোয়াই

1
একটি বিষয় যা আমি ভেবে দেখেছি তা হ'ল সি ++ তে "পোর্টেবল সি" লেখার অর্থ কী হবে কিনা, সেই জাতীয় পরিবর্তনের পরিবর্তে uint16_tযার আচরণ বাস্তবায়ন নির্ভর, একই ধরনের uwrap16এবং unum16যার আচরণ বাস্তবায়ন-স্বাধীন হবে, যেমন uwrap16 w=1; unum16 n=1;অভিব্যক্তি দেওয়া w-2এবং n-2ফলন হবে (uwrap16)65535এবং (int)-1যথাক্রমে [ uint16_tযেখানে int16 বিট রয়েছে এমন সিস্টেমে প্রথম ফল পাওয়া যাবে , এবং দ্বিতীয়টি যেখানে intবড় সেগুলিতে]] সবচেয়ে বড় সমস্যাটি আমি দেখেছিলাম সংখ্যাসূচক অক্ষরগুলি পরিচালনা করা।
সুপারক্যাট

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

উত্তর:


71

এখানে একটি কেস রয়েছে যেখানে কনস্ট্রাক্টর কলের পরিবর্তে ব্যবহারকারী-সংজ্ঞায়িত আক্ষরিক ব্যবহার করার সুবিধা রয়েছে:

#include <bitset>
#include <iostream>

template<char... Bits>
  struct checkbits
  {
    static const bool valid = false;
  };

template<char High, char... Bits>
  struct checkbits<High, Bits...>
  {
    static const bool valid = (High == '0' || High == '1')
                   && checkbits<Bits...>::valid;
  };

template<char High>
  struct checkbits<High>
  {
    static const bool valid = (High == '0' || High == '1');
  };

template<char... Bits>
  inline constexpr std::bitset<sizeof...(Bits)>
  operator"" _bits() noexcept
  {
    static_assert(checkbits<Bits...>::valid, "invalid digit in binary string");
    return std::bitset<sizeof...(Bits)>((char []){Bits..., '\0'});
  }

int
main()
{
  auto bits = 0101010101010101010101010101010101010101010101010101010101010101_bits;
  std::cout << bits << std::endl;
  std::cout << "size = " << bits.size() << std::endl;
  std::cout << "count = " << bits.count() << std::endl;
  std::cout << "value = " << bits.to_ullong() << std::endl;

  //  This triggers the static_assert at compile time.
  auto badbits = 2101010101010101010101010101010101010101010101010101010101010101_bits;

  //  This throws at run time.
  std::bitset<64> badbits2("2101010101010101010101010101010101010101010101010101010101010101_bits");
}

সুবিধাটি হ'ল রান-টাইম ব্যতিক্রম একটি সংকলন-সময় ত্রুটিতে রূপান্তরিত হয়। আপনি স্ট্রিং টেকসই যুক্তি ছাড়াই বিটসেট কর্টারে স্ট্যাটিক এডার যোগ করতে পারেন নি।


7
আপনি স্ট্যান্ড :: বিটসেটকে একটি উপযুক্ত কনটেক্সপ্রিপ কনস্ট্রাক্টর দিয়ে একই কাজ করতে পারেন।
নিকল বোলাস

1
@ নিকোলবোলাস আপনি ঠিক বলেছেন আমি আসলে অবাক হয়েছি সেখানে কেউ নেই। খুব বেশি দেরি না হলে হতে পারে আমাদের 2014 বা একের জন্য প্রস্তাব দেওয়া উচিত।
এমএসআর

192

প্রথম দর্শনে, এটি সাধারণ সিনট্যাকটিক চিনি বলে মনে হচ্ছে।

তবে গভীরতর দিকে তাকালে, আমরা এটি সিনট্যাকটিক চিনির চেয়ে বেশি দেখতে পাই, কারণ এটি ব্যবহারকারী-সংজ্ঞায়িত প্রকারগুলি তৈরি করতে সি ++ ব্যবহারকারীর বিকল্পগুলি প্রসারিত করে যা একেবারে অন্তর্নির্মিত ধরণের মতো আচরণ করে। এতে, এই সামান্য "বোনাস" সি ++ এর সাথে খুব আকর্ষণীয় সি ++ 11 যুক্ত।

আমাদের কি সত্যিই সি ++ এ দরকার?

আমি বিগত বছরগুলিতে আমার লেখা কোডটিতে কয়েকটি ব্যবহার দেখতে পাচ্ছি, তবে কেবলমাত্র আমি এটি সি ++ এ ব্যবহার করি নি তার অর্থ এটি অন্য সি ++ বিকাশকারীদের পক্ষে আকর্ষণীয় নয় ।

সংক্ষিপ্ত বা দীর্ঘ পূর্ণসংখ্যার হিসাবে পূর্ণসংখ্যার সংখ্যা, ভাসা বা দ্বিগুণ (বা এমনকি দীর্ঘ ডাবল) হিসাবে প্রকৃত সংখ্যা এবং স্বাভাবিক বা প্রশস্ত চরিত্র হিসাবে অক্ষরের স্ট্রিং টাইপ করতে আমরা সি ++ (এবং সি-তে আমার অনুমান), সংকলক-সংজ্ঞায়িত আক্ষরিকগুলিতে ব্যবহার করেছি character ।

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

ব্যবহারকারী-প্রকারগুলি অন্তর্নির্মিত ধরনের হিসাবে আচরণ করতে আমরা একটি জিনিস এখনও মিস করেছি: ব্যবহারকারী-সংজ্ঞায়িত আক্ষরিক।

সুতরাং, আমি অনুমান করি এটি ভাষার জন্য একটি প্রাকৃতিক বিবর্তন, তবে যথাসম্ভব পরিপূর্ণ হওয়া: " আপনি যদি কোনও প্রকার তৈরি করতে চান এবং আপনি এটি একটি বিল্ট-ইন টাইপগুলির সাথে যতটা সম্ভব আচরণ করতে চান তবে এখানে সরঞ্জামগুলি রয়েছে are .. "

আমি অনুমান করতে পারি যে এটি বুলিয়ানস, পূর্ণসংখ্যা ইত্যাদি সহ প্রতিটি আদিমকে কাঠামো তৈরি করার এবং নেট এর সিদ্ধান্তের সাথে খুব মিল Ob এই সিদ্ধান্তটিই একা। নেট আদিমদের সাথে কাজ করার সময় জাভা এর নাগালের বাইরে রাখে, জাভা তার স্পেসিফিকেশনে যতই বক্সিং / আনবক্সিং হ্যাক না করে তা বিবেচনা করে না।

আপনার কি সত্যই সি ++ এ দরকার?

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

যদি আপনি এটি প্রয়োজন, তাহলে এটি একটি স্বাগত ছাড়াও। আপনি যদি না করেন, ভাল ... এটি ব্যবহার করবেন না। এটি আপনার জন্য কিছুই ব্যয় করবে।

সি ++ এ স্বাগতম, ভাষা যেখানে বৈশিষ্ট্যগুলি .চ্ছিক।

স্ফীত ??? আমাকে আপনার কমপ্লেক্সটি দেখান !!!

পুষ্পযুক্ত এবং জটিল (পাং উদ্দেশ্যে) এর মধ্যে পার্থক্য রয়েছে।

নীলদের মতো দেখানো হয়েছে যেমন ব্যবহারকারী-সংজ্ঞায়িত আক্ষরিকগুলি C ++নতুন কোন ক্ষমতা যুক্ত করে? , একটি জটিল সংখ্যা লিখতে সক্ষম হওয়াই সি এবং সি ++ এ "সম্প্রতি" যুক্ত হওয়া দুটি বৈশিষ্ট্যের মধ্যে একটি:

// C89:
MyComplex z1 = { 1, 2 } ;

// C99: You'll note I is a macro, which can lead
// to very interesting situations...
double complex z1 = 1 + 2*I;

// C++:
std::complex<double> z1(1, 2) ;

// C++11: You'll note that "i" won't ever bother
// you elsewhere
std::complex<double> z1 = 1 + 2_i ;

এখন, C99 "ডাবল কমপ্লেক্স" টাইপ এবং সি ++ "এসটিডি :: কমপ্লেক্স" টাইপ উভয়ই অপারেটর ওভারলোডিং ব্যবহার করে গুণ, যোগ, বিয়োগ ইত্যাদি করতে সক্ষম।

তবে সি 99 এ তারা একটি বিল্ট-ইন টাইপ এবং বিল্ট-ইন অপারেটর ওভারলোডিং সমর্থন হিসাবে অন্য ধরণের যোগ করেছে। এবং তারা অন্য অন্তর্নির্মিত আক্ষরিক বৈশিষ্ট্য যুক্ত করেছে।

সি ++ তে তারা কেবল ভাষার বিদ্যমান বৈশিষ্ট্যগুলি ব্যবহার করেছিল, দেখেছিল যে আক্ষরিক বৈশিষ্ট্যটি ভাষার প্রাকৃতিক বিবর্তন ছিল এবং এটি এটিকে যুক্ত করেছে।

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

সি ++ 11 এ আপনি নিজে এটি করতে পারেন:

Point p = 25_x + 13_y + 3_z ; // 3D point

ফুলে আছে? না , প্রয়োজন আছে, যেমন দেখানো হয়েছে যে সি এবং সি ++ উভয় কমপ্লেক্সকে কীভাবে তাদের আক্ষরিক জটিল মানগুলি উপস্থাপন করার জন্য একটি উপায় প্রয়োজন।

এটি কি ভুলভাবে ডিজাইন করা হয়েছে? না , এটি এক্সটেনসিবিলিটি মাথায় রেখে প্রতিটি অন্যান্য সি ++ বৈশিষ্ট্য হিসাবে ডিজাইন করা হয়েছে।

এটি কি কেবল চিহ্নিতকরণের জন্য? না , এটি এমনকি আপনার কোডে প্রকারের সুরক্ষা যোগ করতে পারে।

উদাহরণস্বরূপ, আসুন একটি সিএসএস ওরিয়েন্টেড কোডটি কল্পনা করুন:

css::Font::Size p0 = 12_pt ;       // Ok
css::Font::Size p1 = 50_percent ;  // Ok
css::Font::Size p2 = 15_px ;       // Ok
css::Font::Size p3 = 10_em ;       // Ok
css::Font::Size p4 = 15 ;         // ERROR : Won't compile !

মানগুলির অ্যাসাইনমেন্টে শক্ত টাইপিং প্রয়োগ করা তখন খুব সহজ।

বিপদজনক?

ভাল প্রশ্ন. এই ফাংশনগুলি নামগতির হতে পারে? যদি হ্যাঁ, তবে জ্যাকপট!

যাইহোক, সমস্ত কিছুর মতো, কোনও সরঞ্জামকে ভুলভাবে ব্যবহার করা হলে আপনি নিজেকে হত্যা করতে পারেন । সি শক্তিশালী, এবং আপনি যদি সি বন্দুকটির অপব্যবহার করেন তবে আপনি আপনার মাথাটি ছোঁড়াতে পারেন। সি ++ এর কাছে সি বন্দুক রয়েছে, তবে এটি স্কেল্পেল, টিজার এবং অন্য যে কোনও সরঞ্জামটি আপনি এই টুলকিটে খুঁজে পাবেন। আপনি মাথার ত্বকের অপব্যবহার করতে পারেন এবং নিজেকে রক্ত ​​ঝুঁকতে পারেন। অথবা আপনি খুব মার্জিত এবং শক্তিশালী কোড তৈরি করতে পারেন।

সুতরাং, প্রতিটি সি ++ বৈশিষ্ট্যের মতো, আপনার কি সত্যিই এটির প্রয়োজন আছে? এটি আপনাকে সি ++ ব্যবহার করার আগে অবশ্যই উত্তর দিতে হবে। আপনি যদি তা না করেন তবে এটির জন্য আপনার কোনও মূল্য হবে না। তবে আপনার যদি সত্যিই এটির প্রয়োজন হয় তবে অন্তত ভাষাটি আপনাকে হতাশ করে না।

তারিখের উদাহরণ?

আপনার ত্রুটিটি, আমার কাছে মনে হচ্ছে আপনি অপারেটরদের মিশ্রণ করছেন:

1974/01/06AD
    ^  ^  ^

এটি এড়ানো যায় না, কারণ / অপারেটর হওয়ায় সংকলককে অবশ্যই এটি ব্যাখ্যা করতে হবে। এবং, আফাইক, এটি একটি ভাল জিনিস।

আপনার সমস্যার সমাধান খুঁজতে আমি আক্ষরিক অন্য কোনও উপায়ে লিখব। উদাহরণ স্বরূপ:

"1974-01-06"_AD ;   // ISO-like notation
"06/01/1974"_AD ;   // french-date-like notation
"jan 06 1974"_AD ;  // US-date-like notation
19740106_AD ;       // integer-date-like notation

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


1
আপনাকে ধন্যবাদ, আমি এবং আমার অন্যান্য বিকল্প ব্যক্তিত্ব আবিষ্কার করেছি। আরও গুরুতরভাবে, আমি এটি একা লিখেছি, তবে সম্ভবত আমি আমার মাতৃভাষার কিছু প্রকাশ করছি এবং তারা ইংরেজিতে ভাল অনুবাদ করে না te
প্যারাসেবল

"বিভিন্ন অংশ" হিসাবে, যেমন তাদের শিরোনামগুলি দেখায়, দুঃখিত, আমি অনুমান করি এটি কিছুটা দীর্ঘ পোস্টের আয়োজন করে। গা the় পাঠ্য হিসাবে, এটি যে অনুচ্ছেদে রয়েছে তার সংক্ষিপ্তসার jus বিন্যাস ছাড়াই কেবল তথ্যের সন্ধানকারী লোকেরা শিরোনাম এবং গা bold় পাঠ্যের উপর তাদের পড়া সীমাবদ্ধ করতে পারে।
পেরেসারবাল

3
+1 টি। সত্যিই দুর্দান্ত ব্যাখ্যা। আমরা এটি বাস্তবায়নের জন্য অপেক্ষা করছি। এটি আমাদের জন্য সত্যই গুরুত্বপূর্ণ। আমরা এমডিইতে (মডেল-চালিত ইঞ্জিনিয়ারিং) কাজ করি এবং এটি একটি ঘনত্ব খুঁজে পাই। আমি আমাদের কেসটি ব্যাখ্যা করতে নীচে একটি প্রতিক্রিয়া যুক্ত করছি।
দিয়েগো সেভিলা

9
@ টিজিভি:: you can write 1+2i, but you still can't write a+bi, so there's absolutely no pointএমনকি আপনার a+biউদাহরণ উপেক্ষা করা হাস্যকর, এমনকি আপনি এটি "স্বল্প ফ্রিকোয়েন্সি" হিসাবে দেখেন তার অর্থ এই নয় যে সবাই তা করে। । । বৃহত্তর চিত্রটির দিকে লক্ষ্য করা, মূল বিষয়টি নিশ্চিত করা উচিত যে ব্যবহারকারী-সংজ্ঞায়িত অবজেক্টগুলি ভাষার প্রথম শ্রেণির নাগরিক হিসাবে যতটা সম্ভব বিল্ড-ইন প্রকারের হিসাবে বিবেচিত হতে পারে be সুতরাং, আপনি যদি লিখতে পারেন 1.5fএবং 1000UL, কেন আপনি লিখতে 25iবা এমনকি করতে পারেন না 100101b? সি এবং জাভার বিপরীতে, ব্যবহারকারী প্রকারগুলি সি ++ এ ভাষার দ্বিতীয় শ্রেণির নাগরিক হিসাবে বিবেচিত হবে না।
প্যারাসেবল

3
@ অ্যানটন:: কোডে Most of data still comes from IOপ্রচুর হার্ডকোডযুক্ত মান রয়েছে। কোডে আসা সমস্ত বুলিয়ান, সমস্ত পূর্ণসংখ্যার, সমস্ত দ্বিগুণগুলি দেখুন, কারণ যেখানে শক্তিশালী টাইপ করা ধ্রুবক রয়েছে তার x = 2 * y ;পরিবর্তে এটি লিখতে আরও সুবিধাজনক । ব্যবহারকারীর সংজ্ঞায়িত আক্ষরিকাগুলি আমাদের এটির জন্য একটি টাইপ রাখতে, এবং লিখতে সক্ষম করে: এবং সংকলকটি যাচাই করে তা নিশ্চিত করে। । । এটি সবই শক্তিশালী টাইপিং সম্পর্কে আসে। । । সম্ভবত আপনি এটি ব্যবহার করবেন না। তবে আমি নিশ্চিত, আমি যত তাড়াতাড়ি কাজের জায়গায় একটি C ++ 11 সক্ষম সংকলক ব্যবহার করতে সক্ষম হব will x = Two * yTwox = 2_speed * y ;
প্যারাসেবল

36

এটি গাণিতিক কোডের জন্য খুব সুন্দর। আমার মন থেকে আমি নিম্নলিখিত অপারেটরগুলির জন্য ব্যবহার দেখতে পাচ্ছি:

ডিগ্রি জন্য ডিগ্রি। এটি নিখুঁত কোণগুলি লেখাকে আরও স্বজ্ঞাত করে তোলে।

double operator ""_deg(long double d)
{ 
    // returns radians
    return d*M_PI/180; 
}

এটি বিভিন্ন নির্দিষ্ট পয়েন্ট উপস্থাপনার জন্যও ব্যবহার করা যেতে পারে (যা এখনও ডিএসপি এবং গ্রাফিক্সের ক্ষেত্রে ব্যবহৃত হয়)।

int operator ""_fix(long double d)
{ 
    // returns d as a 1.15.16 fixed point number
    return (int)(d*65536.0f); 
}

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


1
"তবে আমাদের কাছে ইতিমধ্যে এতগুলি সরঞ্জামের অপব্যবহার রয়েছে যা আরও একটির ক্ষতি করে না " "বাহ, আমি আশা করি এটি সম্প্রতি যে সি ++ [এক্স] 1234567890 এর বৈশিষ্ট্য বন্যার সমস্তটির পিছনে দর্শন নয়। আপনার সমস্ত কোড ব্যবহারের জন্য কনফিগারেশনের জন্য দশটি ফাইল ফর্ম্যাট এবং আপনার কোডের প্রাক এবং পোস্ট-প্রসেসিংয়ের জন্য দুটি সরঞ্জাম ব্যবহার করার একটি লাইব্রেরি শিখার কল্পনা করুন ...
মাস্টারেক্সিলো

@ মাস্টারেক্সিলো অবশ্যই বাস্তবে আপনার উদাহরণটি অযৌক্তিক: ইউডিএলগুলি ফাংশনগুলির চেয়ে শিখতে আরও বেশি অসুবিধা হয় না, কেবল তাদের জন্য সিনট্যাক্স চিনির মতো - এবং পাশাপাশি কোনও ভাল লিব শুধুমাত্র ইউএক্স উন্নত করার জন্য প্রয়োজনীয় বৈশিষ্ট্যগুলি ব্যবহার করে - এবং ডকুমেন্টগুলি ঠিক কী সব উপায়ে. কেউ যদি অপঠনযোগ্য কোড তৈরি করার জন্য কোনও বৈশিষ্ট্যকে অতিরিক্ত ব্যবহার করে (ধরে নিলেন যে এটি তাদের কাজের লাইনে একেবারেই এড়ানো যায় ...) তবে এটি সেই বৈশিষ্ট্যটিকে দোষে ফেলেছে না, কেবল ব্যবহার। এছাড়াও, এক ব্যক্তির অপঠনযোগ্য অন্যটির রুটি এবং মাখন। এটি সমস্ত মতামত - এবং বিকল্পসমূহ । আপনি তাদের পছন্দ না হলে, চিন্তা করবেন না! আপনি না আছে তাদের ব্যবহার করার জন্য। অন্যরা পারেন
আন্ডারস্কোর_আডি

17

ইউডিএলগুলি নাম-গতিযুক্ত (এবং ঘোষণা / নির্দেশাবলী ব্যবহার করে আমদানি করা যেতে পারে, তবে আপনি স্পষ্টভাবে একটি আক্ষরিকের মতো নাম রাখতে পারবেন না 3.14std::i) যার অর্থ সেখানে (আশা করা যায়) এক টন সংঘর্ষ হবে না।

এগুলি প্রকৃতপক্ষে টেম্পলেট করা যায় (এবং কনস্টেক্সারড ') এর অর্থ হ'ল আপনি ইউডিএলগুলির সাহায্যে বেশ কিছু শক্তিশালী স্টাফ করতে পারেন। বিগিন্ট লেখকরা সত্যিই খুশি হবেন, কারণ শেষ পর্যন্ত তারা সংকলনের সময় গণনা করা হয়েছে (কনটেক্সট্রপ বা টেম্পলেটগুলির মাধ্যমে) নির্বিচারে বড় ধ্রুবক থাকতে পারে।

আমি কেবল দু: খিত যে কল্পিত ইউনিটের sপক্ষে std::stringএবং এর iজন্য আমরা স্ট্যান্ডার্ডে (এটির চেহারা থেকে) কয়েকটি কার্যকর আক্ষরিক দেখতে পাব না ।

কোডিং সময় যে পরিমাণ ইউডিএল দ্বারা সংরক্ষণ করা হবে তা আসলে তত বেশি নয়, তবে পঠনযোগ্যতা ব্যাপকভাবে বৃদ্ধি করা হবে এবং আরও বেশি গণনা দ্রুত সম্পাদনের জন্য সংকলন-সময়ে স্থানান্তরিত হতে পারে।


নেমস্পেসগুলি সম্পর্কে বিন্দুটি পরিষ্কার করার জন্য ধন্যবাদ ... আমি এটি ভাবছিলাম।
নাথন রেড

12

আমাকে কিছুটা প্রসঙ্গে যুক্ত করা যাক। আমাদের কাজের জন্য, ব্যবহারকারী সংজ্ঞায়িত আক্ষরিক অনেক প্রয়োজন। আমরা এমডিইতে (মডেল-চালিত ইঞ্জিনিয়ারিং) কাজ করি। আমরা সি ++ তে মডেল এবং মেটোমোডেল সংজ্ঞায়িত করতে চাই। আমরা বাস্তবে ইকোর থেকে সি ++ ( EMF4CPP ) তে ম্যাপিং প্রয়োগ করেছি ।

C ++ ক্লাস হিসাবে মডেল উপাদানগুলি সংজ্ঞায়িত করতে সক্ষম হওয়ায় সমস্যাটি আসে। আমরা আর্গুমেন্টের সাহায্যে টেমপ্লেটগুলিতে মেটামোডেল (ইকোর) রুপান্তর করার পদ্ধতি গ্রহণ করছি। টেমপ্লেটের আর্গুমেন্টগুলি ধরণ এবং শ্রেণীর কাঠামোগত বৈশিষ্ট্য। উদাহরণস্বরূপ, দুটি int গুণাবলী সহ একটি শ্রেণি এমন হবে:

typedef ::ecore::Class< Attribute<int>, Attribute<int> > MyClass;

তবুও, এটি দেখা যায় যে কোনও মডেল বা মেটামোডেলের প্রতিটি উপাদানগুলির একটি নাম থাকে। আমরা লিখতে চাই:

typedef ::ecore::Class< "MyClass", Attribute< "x", int>, Attribute<"y", int> > MyClass;

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

typedef ::ecore::Class< MyClass_n, Attribute< x_n, int>, Attribute<y_n, int> > MyClass;

পরিশেষে, এই সংজ্ঞাগুলি টেমপ্লেট হিসাবে থাকা আমাদেরকে মডেল উপাদানগুলি, মডেল ট্রান্সফর্মেশন ইত্যাদি ট্র্যাভারিংয়ের জন্য অ্যালগরিদমগুলি তৈরি করতে অনেক সহায়তা করে যা সত্যই দক্ষ, কারণ টাইপ তথ্য, সনাক্তকরণ, রূপান্তরকরণ ইত্যাদি সংকলনের সময় সংকলক দ্বারা নির্ধারিত হয়।


4
আমি চাই অনেক অনেকby the compiler at compile time অংশ ... :-)
paercebal

12

টাইপ সমৃদ্ধ ইন্টারফেসের প্রথম বিভাগে, প্রায় 20 মিনিটের চিহ্নের মধ্যে এই সি ++ 11 আলাপে ইউডিএল সম্পর্কে বার্জার স্ট্রস্ট্রপ কথা বলেছেন ।

ইউডিএলগুলির জন্য তাঁর প্রাথমিক তর্কটি পাঠ্যক্রমের রূপ নেয়:

  1. "তুচ্ছ" প্রকার, অর্থাত্ অন্তর্নির্মিত আদিম প্রকারগুলি কেবল তুচ্ছ টাইপের ত্রুটিগুলি ধরতে পারে। সমৃদ্ধ ধরণের সাথে ইন্টারফেসগুলি টাইপ সিস্টেমকে আরও ধরণের ত্রুটি ধরতে দেয়।

  2. ধরণের টাইপের ত্রুটিগুলি যা প্রচুর পরিমাণে টাইপ করা কোডটি রিয়েল কোডে প্রভাব ফেলতে পারে। (তিনি মঙ্গল জলবায়ু অরবিটারের উদাহরণ দিয়েছেন যা একটি গুরুত্বপূর্ণ ধ্রুবকটিতে ত্রুটির কারণে তীব্রভাবে ব্যর্থ হয়েছিল)।

  3. বাস্তব কোডে, ইউনিটগুলি খুব কমই ব্যবহৃত হয়। লোকেরা এগুলি ব্যবহার করে না, কারণ সমৃদ্ধ ধরণের তৈরি করতে রানটাইম গণনা বা মেমরি ওভারহেড ব্যয় করা খুব ব্যয়বহুল, এবং প্রাক-বিদ্যমান সি ++ টেম্প্লেটেড ইউনিট কোডটি ব্যবহার করা এতটাই কুৎসিত যে কেউ এটি ব্যবহার করে না। (অভিজ্ঞতার সাথে, গ্রন্থাগারগুলি প্রায় এক দশক ধরে থাকলেও কেউ এটি ব্যবহার করে না)।

  4. অতএব, প্রকৃত কোডে প্রকৌশলীগুলি ইউনিটগুলি ব্যবহার করার জন্য, আমাদের এমন একটি ডিভাইস প্রয়োজন যা (1) কোনও রানটাইম ওভারহেড না জড়ায় এবং (2) স্বীকৃতিস্বরূপ গ্রহণযোগ্য।


9

সংকলন-সময় মাত্রা যাচাইকরণ সমর্থন কেবলমাত্র ন্যায়সঙ্গততা প্রয়োজন।

auto force = 2_N; 
auto dx = 2_m; 
auto energy = force * dx; 

assert(energy == 4_J); 

উদাহরণস্বরূপ দেখুন সংকলন-সময়ীয় মাত্রিক বিশ্লেষণ এবং ইউনিট / পরিমাণের কারসাজি এবং রূপান্তরকরণের জন্য ফিজিউনিটস-সিটি- সিপিপি 11, একটি ছোট সি ++ 11, সি ++ 14 হেডার-কেবল লাইব্রেরি। চেয়ে সহজ Boost.Units , সমর্থন করে ইউনিট প্রতীক যেমন মি, ছ, এস, যেমন লিটারেল মেট্রিক উপসর্গ , যেমন মি, ট, এম হিসাবে শুধুমাত্র মান সি ++ গ্রন্থাগার, এসআই-শুধুমাত্র মাত্রার অবিচ্ছেদ্য ক্ষমতা উপর নির্ভর করে।


অথবা ইউনিটগুলি দেখুন , একটি সংকলন-সময়, কেবলমাত্র শিরোনাম, মাত্রিক বিশ্লেষণ এবং ইউনিট রূপান্তর গ্রন্থাগার সি ++ 14-এ নির্মিত হয়েছে নিক হলথাসের কোনও নির্ভরতা ছাড়াই ।
মার্টিন মোইন

6

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

assert(1_kg == 2.2_lb); // give or take 0.00462262 pounds

... আমি অবাক হয়েছি আপনি আজ কীভাবে তা প্রকাশ করলেন। আপনার কাছে কেজি এবং এলবি ক্লাস ছিল এবং আপনি অন্তর্নিহিত বস্তুর তুলনা করতে পারেন:

assert(KG(1.0f) == LB(2.2f));

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

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

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

আহ, আমার পোস্টটি মূলত কিছুই বলে না: এটি ঠিক হয়ে যাচ্ছে, প্রভাব খুব বেশি হবে না। আসুন চিন্তা করবেন না। :-)


5
আপনার বন্ধনী ভারসাম্যহীন! দুঃখিত, আমার ওসিডি আমাকেও ঘৃণা করে।
এক্স-ইজুশন

3

আমি কখনও এই বৈশিষ্ট্যটির প্রয়োজন বা চাইনি (তবে এটি ব্লব প্রভাব হতে পারে )। আমার হাঁটু কটূক্ত প্রতিক্রিয়াটি হ'ল এটি লম্পট এবং সম্ভবত একই লোকদের কাছে আবেদন করার সম্ভাবনা রয়েছে যারা মনে করেন যে এটি অপারেটিং + কে যে কোনও অপারেশনের জন্য দূরবর্তীভাবে যোগ হিসাবে গণ্য করা যেতে পারে load


আমি নিশ্চিত: খুব আকর্ষণীয় নিবন্ধ।
প্যারাজবাল

2

সি ++ সাধারণত ব্যবহৃত সিনট্যাক্স সম্পর্কে খুব কঠোর - প্রিপ্রসেসর বাদ দিয়ে কোনও কাস্টম বাক্য গঠন / ব্যাকরণ সংজ্ঞায়িত করতে আপনি তেমন ব্যবহার করতে পারবেন না। যেমন আমরা বিদ্যমান অপেরাটোসকে ওভারলোড করতে পারি, তবে আমরা নতুনকে সংজ্ঞায়িত করতে পারি না - আইএমও এটি সি ++ এর স্পিরিটের সাথে সঙ্গতিপূর্ণ।

আমি আরও কাস্টমাইজড উত্স কোডের জন্য কিছু উপায়ে আপত্তি করি না - তবে নির্বাচিত পয়েন্টটি আমার কাছে খুব বিচ্ছিন্ন বলে মনে হচ্ছে, যা আমাকে সবচেয়ে বেশি বিভ্রান্ত করে।

এমনকি উত্সযুক্ত ব্যবহারটি উত্স কোডটি পড়া আরও বেশি শক্ত করে তুলতে পারে: একটি একক বর্ণের প্রসারিত পার্শ্ব প্রতিক্রিয়া হতে পারে যা কোনও উপায়েই প্রসঙ্গ থেকে চিহ্নিত করা যায় না। ইউ, এল এবং এফ এর প্রতিসাম্য সহ বেশিরভাগ বিকাশকারী একক বর্ণ চয়ন করবেন।

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

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

আমি অবাক হয়ে যাই, তবে আমরা কী চালাক ধারণা নিয়ে আসি।


1
using single letters in global namespace will probably be considered bad practiceতবে এর কোনও প্রাসঙ্গিকতা নেই: (ক) ইউডিএলগুলি অবশ্যই (অ-গ্লোবাল) নেমস্পেস স্কোপে সংজ্ঞায়িত করা উচিত ... সম্ভবত কারণ (বি) তাদের অবশ্যই একটি চিঠি নয়, তবে কেবল = চিঠি নয় এবং এর মধ্যে শনাক্তকারী গ্লোবাল এনএস বাস্তবায়নের জন্য সংরক্ষিত। এটি ইউডিএলরা সহজাত বিভ্রান্তি সৃষ্টি করে এমন ধারণার বিরুদ্ধে কমপক্ষে 2 টি পয়েন্ট। বৈশিষ্ট্যটির ইউটিলিটি হ্রাস করার জন্য স্পেস নেমস্পেসে থাকার কারণে, যেমন স্টাডলিব তাদের এ ঘোষণা করে inline namespaceযে ব্যবহারকারীরা চাইলে পাইকারি আমদানি করতে পারবেন।
আন্ডারস্কোর_আডি

2

আমি বাইনারি স্ট্রিংয়ের জন্য ব্যবহারকারীর লিটারালগুলি এইভাবে ব্যবহার করেছি:

 "asd\0\0\0\1"_b

std::string(str, n)কনস্ট্রাক্টর ব্যবহার করে যাতে \0স্ট্রিংটি অর্ধেক না কেটে দেয়। (প্রকল্পটি বিভিন্ন ফাইল ফর্ম্যাট দিয়ে প্রচুর কাজ করে))

আমি যখন std::stringএকটি মোড়কের পক্ষে খাপ খাই তখন এটিও সহায়ক ছিল std::vector


-5

এই জিনিসটিতে লাইন গোলমাল বিশাল। এটি পড়তে ভয়ঙ্করও বটে।

আমাকে জানতে দিন, তারা কি নতুন সিনট্যাক্স যুক্ত করে কোনও ধরণের উদাহরণ দিয়ে যুক্ত করেছেন? উদাহরণস্বরূপ, তাদের কি এমন বেশ কয়েকটি প্রোগ্রাম রয়েছে যা ইতিমধ্যে C ++ 0x ব্যবহার করে?

আমার জন্য, এই অংশ:

auto val = 3.14_i

এই অংশটি ন্যায্যতা দেয় না:

std::complex<double> operator ""_i(long double d) // cooked form
{ 
    return std::complex(0, d);
}

এমনকি আপনি যদি 1000 অন্যান্য লাইনেও আই-সিনট্যাক্স ব্যবহার করেন তবে তা নয়। আপনি যদি লিখেন তবে আপনি সম্ভবত পাশাপাশি অন্য কিছু 10000 লাইন লিখুন। বিশেষত আপনি যখন এখনও সম্ভবত বেশিরভাগ জায়গায় এই লিখবেন:

std::complex<double> val = 3.14i

'অটো' -শব্দটি কেবলমাত্র, যদিও যুক্তিযুক্ত হতে পারে। তবে কেবল সি ++ নেওয়া যাক, কারণ এই দিক থেকে এটি সি ++ 0x এর চেয়ে ভাল।

std::complex<double> val = std::complex(0, 3.14);

এটা মত .. যে সহজ। এমনকি আপনি যদি সর্বত্র ব্যবহার করেন তবে সমস্ত স্ট্যান্ড এবং পয়েন্টযুক্ত বন্ধনীগুলি কেবল লম্বা are এইচডি :: কমপ্লেক্সকে কমপ্লেক্সে পরিণত করার জন্য সি ++ 0x এর মধ্যে কোন সিনট্যাক্স রয়েছে তা অনুমান করা শুরু করি না।

complex = std::complex<double>;

এটি সম্ভবত সোজা কিছু, তবে আমি বিশ্বাস করি না যে এটি সি ++ 0x এ এত সহজ।

typedef std::complex<double> complex;

complex val = std::complex(0, 3.14);

সম্ভবত? > :)

যাইহোক, মূল কথাটি: স্ট্যান্ড :: জটিল (0, 3.14) এর পরিবর্তে 3.14i লেখা; কয়েকটি সুপার বিশেষ ক্ষেত্রে বাদে সামগ্রিকভাবে আপনাকে বেশি সময় বাঁচায় না।


10
@ চ্যারি: আপনার জন্য, "অটো ভাল = 3.14i" এটি সমর্থন করার জন্য লিখিত কোডটিকে ন্যায়সঙ্গত করে না। আমি উত্তর দিতে পারি, আমার জন্য "প্রিন্টফ ("% আমি ", 25)" প্রিন্টফের জন্য লিখিত কোডটিকে ন্যায়সঙ্গত করে না। আপনি একটি প্যাটার্ন দেখতে পাচ্ছেন?
পেরেসারবাল

5
@ চেরি: "এই জিনিসটির মধ্যে লাইন গোলমাল বিশাল"। না, এটি নয় ... "এছাড়াও এটি পড়তে ভয়ঙ্কর"। আপনার বিষয়গত যুক্তি আকর্ষণীয়, তবে এই বৈশিষ্ট্যটির কোডটি অবাক করা / অবাক করা থেকে দূরে দেখার জন্য আপনার সাধারণভাবে অপারেটর ওভারলোডিংয়ের দিকে নজর দেওয়া উচিত ... একটি সি ++ বিকাশকারী
প্যারাসেবল

3
অটো পাঠযোগ্যতায় সহায়তা করবে। একটি লুপের জন্য ইন্টারেটারগুলি ব্যবহার করার বিষয়টি বিবেচনা করুন: (স্বয়ংক্রিয়ভাবে এটি = vec.begin (); এটি! = vec.end (); ++ এটি) ... আমি for_each সম্পর্কে জানি, তবে এটি ব্যবহারের জন্য একটি ফান্টর তৈরি করতে অপছন্দ করি ।
কিটসুনওয়াইএমজি

1
@ কেটিএস: সি ++ ১x এর সাথে আমাদের ল্যাম্বদা এবং ব্যাপ্তি থাকবে
জো ডি

3
যদি আপনার C ++ লাইনটি C ++ 0x এর চেয়ে ভাল হয় তবে আমার লাইনটি আরও ভাল। শুধু লিখুন: std::complex<double> val(0, 3.14);
বেন ভয়েগট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.