সি ++ এ "ব্যবহার" কীওয়ার্ডের পিছনে যুক্তি কী?


145

সি ++ এ কীওয়ার্ড "ব্যবহার" করার পিছনে যুক্তি কী?

এটি বিভিন্ন পরিস্থিতিতে ব্যবহৃত হয় এবং আমি অনুসন্ধান করার চেষ্টা করছি যে তাদের সকলের মধ্যে কিছু মিল রয়েছে কিনা এবং "ব্যবহার" কীওয়ার্ডটি যেমন ব্যবহার করা হচ্ছে তার কারণ রয়েছে।

using namespace std; // to import namespace in the current namespace
using T = int; // type alias
using SuperClass::X; // using super class methods in derived class

53
স্ট্যান্ডার্ড কমিটিকে C ++ ব্যাকরণে নতুন কীওয়ার্ড প্রবর্তন করা ঘৃণা করে।
তেহ ইন্টারনেটস

4
@teinternetsismadeofcatz যদি সত্যিই যুক্তি হয় তবে দয়া করে আমাকে ক্ষমা করুন আমি এখন গিয়ে নিজেকে হত্যা করব।
ব্যবহারকারী3111311

62
@ ইউজার ৩১১১১১১১: আপনি নতুন সংরক্ষিত শব্দের প্রবর্তন করার অর্থ বোঝেন, তাই না? এর অর্থ হ'ল যে সমস্ত বিদ্যমান কোড যা সনাক্তকারী নাম হিসাবে ব্যবহার করে তা হঠাৎ সংকলন করতে ব্যর্থ হয়। এটি একটি খারাপ জিনিস। উদাহরণস্বরূপ, প্রচুর সি কোড রয়েছে যা সি ++ হিসাবে সংকলন করতে পারে না কারণ এতে রয়েছে এর মতো জিনিস int class;। এটি আরও খারাপ হবে যদি সি ++ কোড হঠাৎ করে বৈধ সি ++ হওয়া বন্ধ করে দেয়।
বেন ভয়েগ্ট

7
@ বেনভয়েগ্ট: সি কোড ব্যবহার করে int class;সি ++ হিসাবে সংকলিত হবে না এটি সম্পূর্ণ খারাপ জিনিস নয়। এটি গ্যারান্টি হিসাবে ব্যবহার করা যেতে পারে যে সি কোড সি হিসাবে সংকলিত হবে এটি ভুলে যাওয়া খুব সহজ যে সি এবং সি ++ দুটি পৃথক ভাষা - এবং, ব্যবহারিকভাবে বলতে গেলে এমন কোড রয়েছে যা বৈধ সি এবং বৈধ সি ++, তবে বিভিন্ন শব্দার্থবিজ্ঞানের সাথে।
কিথ থমসন

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

উত্তর:


114

সি ++ 11-এ, usingকীওয়ার্ডটি ব্যবহার করার সময় ব্যবহৃত type aliasহয় typedef

7.1.3.2

একটি টাইপিডেফ-নাম একটি উপ-ঘোষণার মাধ্যমেও চালু করা যেতে পারে। ব্যবহারকারীর কীওয়ার্ড অনুসরণ করে শনাক্তকারী টাইডেফ-নাম হয়ে যায় এবং typচ্ছিক বৈশিষ্ট্য-নির্দিষ্টকরণকারী-সিক সনাক্তকারীকে অনুসরণ করে সেই টাইপডেফ-নামের সাথে পরিচিত হয়। এটিতে একই শব্দার্থকতা রয়েছে যেমন এটি টাইপডেফ স্পেসিফায়ার দ্বারা প্রবর্তিত হয়েছিল। বিশেষত, এটি কোনও নতুন ধরণের সংজ্ঞা দেয় না এবং এটি টাইপ-আইডিতে প্রদর্শিত হবে না।

বাজার্ন স্ট্রস্ট্রপ একটি ব্যবহারিক উদাহরণ প্রদান করে:

typedef void (*PFD)(double);    // C style typedef to make `PFD` a pointer to a function returning void and accepting double
using PF = void (*)(double);    // `using`-based equivalent of the typedef above
using P = [](double)->void; // using plus suffix return type, syntax error
using P = auto(double)->void // Fixed thanks to DyP

প্রাক-সি ++ 11, usingকীওয়ার্ড সদস্য ফাংশনগুলিকে সুযোগে আনতে পারে। সি ++ 11 এ আপনি এখন এটি নির্মাণকারীর জন্য করতে পারেন (অন্য একটি বাজন স্ট্রস্ট্রপ উদাহরণ):

class Derived : public Base { 
public: 
    using Base::f;    // lift Base's f into Derived's scope -- works in C++98
    void f(char);     // provide a new f 
    void f(int);      // prefer this f to Base::f(int) 

    using Base::Base; // lift Base constructors Derived's scope -- C++11 only
    Derived(char);    // provide a new constructor 
    Derived(int);     // prefer this constructor to Base::Base(int) 
    // ...
}; 

বেন ভয়েট কোনও নতুন কীওয়ার্ড বা নতুন সিনট্যাক্স প্রবর্তন না করার যৌক্তিকতার পিছনে বেশ ভাল কারণ সরবরাহ করে। স্ট্যান্ডার্ডটি যতটা সম্ভব পুরানো কোডটি ভাঙতে চায়। এই জন্যই প্রস্তাব নথি আপনি বিভাগে মত দেখতে হবে Impact on the Standard, Design decisionsএবং তারা পুরোনো কোড কিভাবে প্রভাবিত করতে পারে। এমন পরিস্থিতি রয়েছে যখন প্রস্তাবটি সত্যিই খুব ভাল ধারণা বলে মনে হয় তবে এর ট্রেশন নাও থাকতে পারে কারণ এটি কার্যকর করা খুব কঠিন, খুব বিভ্রান্তিকর, বা পুরানো কোডের বিরোধিতা করবে।


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

প্রথমে খেলনার উদাহরণ বিবেচনা করা যাক:

template <typename T>
class MyAlloc {/*...*/};

template <typename T, class A>
class MyVector {/*...*/};

template <typename T>

struct Vec {
typedef MyVector<T, MyAlloc<T> > type;
};
Vec<int>::type p; // sample usage

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

template <typename T> void foo (Vec<T>::type&);

সুতরাং, সিনট্যাক্সটি কিছুটা কুৎসিত। আমরা নীচে থাকা কিছু এড়াতে ::type চাই আমরা নীচের মতো কিছু পছন্দ করব:

template <typename T>
using Vec = MyVector<T, MyAlloc<T> >; //defined in section 2 below
Vec<int> p; // sample usage

নোট করুন যে আমরা বিশেষত "টাইপিডেফ টেম্পলেট" শব্দটি এড়িয়ে চলেছি এবং বিভ্রান্তি এড়াতে সহায়তার জন্য জুটি "ব্যবহার" এবং "=" জড়িত নতুন সিনট্যাক্সটি প্রবর্তন করছি: আমরা এখানে কোনও প্রকারের সংজ্ঞা দিচ্ছি না, আমরা একটি প্রতিশব্দ (অর্থাত্ উপনাম) প্রবর্তন করছি টেমপ্লেটের প্যারামিটারগুলিতে জড়িত কোনও টাইপ-আইডি (অর্থাত্ টাইপ এক্সপ্রেশন) এর বিমূর্ততা। যদি টেম্পলেট প্যারামিটারগুলি টাইপ এক্সপ্রেশনটিতে ছাড়যোগ্য প্রসঙ্গে ব্যবহৃত হয় তবে যখনই টেম্পলেট উলেসটি টেম্পলেট-আইডি তৈরি করতে ব্যবহৃত হয়, তখনই সংশ্লিষ্ট টেম্পলেট প্যারামিটারের মানগুলি হ্রাস করা যায় - এর আরও আরও অনুসরণ করা হবে। যে কোনও ক্ষেত্রে, এখন জেনেরিক ফাংশনগুলি লিখতে পারবেন যা Vec<T>ছাড়যোগ্য প্রসঙ্গে কাজ করে এবং বাক্য গঠনটিও উন্নত হয়। উদাহরণস্বরূপ আমরা foo পুনরায় লিখতে পারি:

template <typename T> void foo (Vec<T>&);

আমরা এখানে আন্ডারস্কোর করছি যে টেম্পলেট এলিয়াস প্রস্তাব করার প্রাথমিক কারণগুলির মধ্যে একটি ছিল যাতে যুক্তি ছাড় এবং কলটি foo(p) সফল হবে।


ফলো-আপ কাগজ n1489 ব্যাখ্যা করে কেন usingব্যবহারের পরিবর্তে typedef:

টেম্পলেট উপকরণ উপস্থাপনের জন্য কাগজ [4] - - তে টাইপএইফ মূল শব্দটি (পুনরায়) ব্যবহার করার পরামর্শ দেওয়া হয়েছে:

template<class T> 
    typedef std::vector<T, MyAllocator<T> > Vec;

এই স্বরলিপিটির মধ্যে ইতিমধ্যে একটি প্রকারের নাম উপস্থাপনের জন্য পরিচিত একটি কীওয়ার্ড ব্যবহার করার সুবিধা রয়েছে। যাইহোক, এটি বেশ কয়েকটি অসুবিধাগুলিও প্রদর্শন করে যার মধ্যে একটি প্রকারভেদে কোনও উপ-নামের জন্য একটি উপনাম পরিচয় করানোর জন্য পরিচিত কোনও কীওয়ার্ড ব্যবহার করার বিভ্রান্তি যেখানে উলামের কোনও প্রকার নয়, তবে একটি টেম্পলেট নির্ধারণ করে; Vecকোনও প্রকারের জন্য একটি উপনাম নয়, এবং টাইপডেফ-নামের জন্য নেওয়া উচিত নয়। নামটি Vecপরিবারের একটি নাম std::vector< [bullet] , MyAllocator< [bullet] > > - যেখানে বুলেটটি কোনও টাইপ-নামের জন্য স্থানধারক। ফলস্বরূপ আমরা "টাইপডিফ" সিনট্যাক্স প্রস্তাব করি না। অন্যদিকে বাক্যটি

template<class T>
    using Vec = std::vector<T, MyAllocator<T> >;

এটি পড়তে / ব্যাখ্যা করা যায়: এখন থেকে, আমি এর Vec<T>প্রতিশব্দ হিসাবে ব্যবহার করব std::vector<T, MyAllocator<T> >। সেই পাঠের সাথে, এলিয়াসিংয়ের জন্য নতুন সিনট্যাক্সটি যুক্তিসঙ্গত মনে হয়।

আমি মনে করি গুরুত্বপূর্ণ পার্থক্য এখানে তৈরি হয়, ওরফে পরিবর্তে ES টাইপ গুলি। একই নথির আরও একটি উদ্ধৃতি:

একটি উপনাম-ঘোষণা একটি ঘোষণা, এবং সংজ্ঞা নয়। একটি উপনাম-ঘোষণার ঘোষণার ডান-হাত দ্বারা মনোনীত প্রকারের জন্য একটি উপন্যাস হিসাবে একটি ঘোষণামূলক অঞ্চলে একটি নাম প্রবর্তন করে। এই প্রস্তুতির মূলটি নিজেই টাইপ নামের এলিয়াসগুলি নিয়ে উদ্বেগ প্রকাশ করে, তবে স্বরলিপিটি স্পষ্টতই নেমস্পেস-এলিয়াসিং বা ওভারলোডেড ফাংশনগুলির নামকরণের সেট বিকল্পের বানান প্রদান করতে (আরও আলোচনার জন্য ✁ 2.3 দেখুন) জেনারেল করা যেতে পারে। [ আমার দ্রষ্টব্য: section বিভাগটি সেই সিনট্যাক্সটি দেখতে কী হতে পারে এবং কেন এটি প্রস্তাবের অংশ নয় তা নিয়ে আলোচনা করা হয়েছে। ] এটি লক্ষণীয় যে ব্যাকরণ উত্পাদনের উপনাম-ঘোষণা যে কোনও জায়গায় টাইপডেফ ঘোষণা বা একটি নেমস্পেস-ওরফে-সংজ্ঞা গ্রহণযোগ্য।

ভূমিকা জন্য সংক্ষিপ্তসার using:

  • টেমপ্লেট অ্যালিয়াস (বা টেম্পলেট টাইপডেফ, পূর্বের নামটিই পছন্দমতো)
  • নেমস্পেসের নাম (যেমন namespace PO = boost::program_optionsএবং using PO = ...সমতুল্য)
  • নথি বলে A typedef declaration can be viewed as a special case of non-template alias-declaration। এটি একটি নান্দনিক পরিবর্তন, এবং এক্ষেত্রে অভিন্ন হিসাবে বিবেচিত হয়।
  • সুযোগে কিছু আনয়ন (উদাহরণস্বরূপ, namespace stdবৈশ্বিক সুযোগে), সদস্য ফাংশন, উত্তরাধিকারী কনস্ট্রাক্টর

এটি এর জন্য ব্যবহার করা যাবে না :

int i;
using r = i; // compile-error

পরিবর্তে করুন:

using r = decltype(i);

ওভারলোডের একটি সেট নামকরণ।

// bring cos into scope
using std::cos;

// invalid syntax
using std::cos(double);

// not allowed, instead use Bjarne Stroustrup function pointer alias example
using test = std::cos(double);

2
@ user3111311 আপনার কী কীওয়ার্ডটি মনে আছে? "অটো"? "নিবন্ধন"?
রেমন্ড চেন

2
using P = [](double)->void;, আফাইক, বৈধ সি ++ 11 নয়। তবে এটি হ'ল: using P = auto(double)->void;এবং একটি ফাংশনের ধরণের উত্পাদন করে (যেমন এটি P*কোনও ফাংশন পয়েন্টার)।
ডিসি


1
@ রেমন্ডচেন: আসলে registerখুব খারাপ লাগবে না, এতে রয়েছে:register X as Y
এমএফএইচ

1
দুর্ভাগ্যক্রমে registerএকটি পরিবর্তনশীল ঘোষণা শুরু হয় সুতরাং এর ইতিমধ্যে একটি অর্থ রয়েছে। টাইপ এক্স এর ওয়াই নামক একটি রেজিস্টার ভেরিয়েবল ঘোষণা করুন
রায়মন্ড চেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.