বৈকল্পিক টেম্পলেটগুলির প্রসঙ্গে "…" টোকেনের নিয়ম কী?


99

সি ++ 11 তে এই জাতীয় মত বৈকল্পিক টেম্পলেট রয়েছে:

template< class T, class... Args >
unique_ptr<T> make_unique( Args&&... args )
{
    return unique_ptr<T>(new T(std::forward<Args>(args)...));
}

এটি সম্পর্কে কিছু কৌতূহল রয়েছে: এক্সপ্রেশনটি std::forward<Args>(args)...উভয় Argsএবং argsকেবলমাত্র একটি ...টোকেন ব্যবহার করে। উপরন্তু std::forwardএকটি অ-variadic টেমপ্লেট ফাংশন শুধুমাত্র একটি টেমপ্লেট প্যারামিটার এবং এক যুক্তি গ্রহণ করা হয়। এর সিনট্যাক্স বিধিগুলি কী (মোটামুটিভাবে)? কীভাবে এটি সাধারণীকরণ করা যায়?

এছাড়াও: ফাংশন বাস্তবায়নে উপবৃত্ত ( ...) আগ্রহের প্রকাশের শেষে হয়। টেমপ্লেট আর্গুমেন্ট তালিকার এবং পরামিতি তালিকায় এলিপসিসটি মাঝখানে রয়েছে এমন কোনও কারণ আছে কি?


4
সংক্ষেপে দ্বিতীয় অংশে: যখন কোনও টেম্পলেট প্যারামিটার প্যাক বা ফাংশন প্যারামিটার প্যাকটি "ঘোষণা" করেন, ...তখন শনাক্তকারী পরিচয় করানোর আগে আসে। উভয় বা উভয় ধরণের প্যাকগুলি ব্যবহার ...করার সময়, এক্সপ্রেশন প্যাটার্নটি প্রসারিত হওয়ার পরে আসে।
aschepler

উত্তর:


99

বৈকল্পিক টেমপ্লেটের প্রসঙ্গে, উপবৃত্তাকারটি ...টেম্পলেট প্যারামিটার প্যাকটি আনপ্যাক করার জন্য ব্যবহৃত হয় যদি এটি কোনও অভিব্যক্তির ডানদিকে উপস্থিত হয় (এই মুহূর্তের জন্য এই এক্সপ্রেশন প্যাটার্নটি কল করুন ), বা এটি একটি প্যাক আর্গুমেন্ট যদি এটি বাম দিকে প্রদর্শিত হয় নাম:

...thing  // pack   : appears as template arguments
thing...  // unpack : appears when consuming the arguments

নিয়মটি হ'ল যে বাম দিকের যে প্যাটার্নটি রয়েছে ...তার পুনরাবৃত্তি হয় - আনপ্যাক করা নিদর্শনগুলি ( এখনই তাদেরকে এক্সপ্রেশন বলুন ) কমা দ্বারা পৃথক করা হয়েছে ,

এটি কয়েকটি উদাহরণ দ্বারা ভালভাবে বোঝা যায়। ধরুন আপনার কাছে এই ফাংশন টেম্পলেট রয়েছে:

template<typename ...T> //pack
void f(T ... args)      //pack
{
   // here are unpack patterns

   g( args... );        //pattern = args
   h( x(args)... );     //pattern = x(args)
   m( y(args...) );     //pattern = args (as argument to y())
   n( z<T>(args)... );  //pattern = z<T>(args)
}

এখন আমি যদি এই ফাংশনটিকে পাস Tহিসাবে কল করি {int, char, short}তবে তার প্রতিটি ফাংশন কলকে এইভাবে প্রসারিত করা হবে:

g( arg0, arg1, arg2 );           
h( x(arg0), x(arg1), x(arg2) );
m( y(arg0, arg1, arg2) );
n( z<int>(arg0), z<char>(arg1), z<short>(arg2) );

আপনি যে কোড পোস্ট std::forwardকরেছেন তাতে n()ফাংশন কল দ্বারা চিত্রিত চতুর্থ প্যাটার্ন অনুসরণ করে ।

x(args)...এবং এর মধ্যে পার্থক্য নোট করুন y(args...)!


আপনি ...অ্যারে আরম্ভ করার জন্য এটিও ব্যবহার করতে পারেন :

struct data_info
{
     boost::any  data;
     std::size_t type_size;
};

std::vector<data_info> v{{args, sizeof(T)}...}; //pattern = {args, sizeof(T)}

যা এটিতে প্রসারিত:

std::vector<data_info> v 
{ 
   {arg0, sizeof(int)},
   {arg1, sizeof(char)},
   {arg2, sizeof(short)}
};

আমি কেবল বুঝতে পেরেছি যে কোনও প্যাটার্নে এমনকি অ্যাক্সেস সুনির্দিষ্ট যেমন অন্তর্ভুক্ত থাকতে পারে যেমন publicনিম্নলিখিত উদাহরণে দেখানো হয়েছে:

template<typename ... Mixins>
struct mixture : public Mixins ...  //pattern = public Mixins
{
    //code
};

এই উদাহরণে, প্যাটার্নটি এই হিসাবে প্রসারিত হয়েছে:

struct mixture__instantiated : public Mixin0, public Mixin1, .. public MixinN  

এটি হ'ল সমস্ত বেস ক্লাস mixtureথেকে প্রকাশ্যে আসে।

আশা করি এইটি কাজ করবে.


4
মিলে যায় এমন অভিব্যক্তি সম্পর্কে; এটি সবচেয়ে বড় সম্ভাব্য এক্সপ্রেশন হওয়া উচিত, তাই না? উদাহরণস্বরূপ x+args...প্রসারিত করা উচিত x+arg0,x+arg1,x+arg2, না x+arg0,arg1,arg2
বিটমাস্ক

সুতরাং ...প্যাটার্নে প্রতিটি বিস্তৃত সত্তার জন্য প্রযোজ্য।
অরবিটে হালকাতা রেস

@ বিটমাস্ক: হ্যাঁ x+args...প্রসারিত করা উচিত x+arg0,x+arg1,x+arg2, না x+arg0,arg1,arg2
নওয়াজ

4
@ জারোড 42: সি ++ 17 প্রকাশের পরে আমি এই উত্তরটি আপডেট করব।
নওয়াজ

4
@ সেন্টার: sizeof...(T)সেখানে দরকার নেই। আপনি কেবল লিখতে পারেন:int a[] = { ___ };
নওয়াজ

48

নীচে GoingNative 2012 এ আন্দ্রে আলেকজান্দ্রেস্কুর "ভারিয়াদিক টেম্পলেটগুলি ফানাদিক" শীর্ষক আলাপ থেকে নেওয়া হয়েছে vari আমি এটি বৈকল্পিক টেম্পলেটগুলির জন্য একটি ভাল পরিচিতির জন্য সুপারিশ করতে পারি।


একটি ভ্যারিয়েডিক প্যাক দিয়ে দুটি জিনিস করতে পারে। sizeof...(vs)উপাদানগুলির সংখ্যা পেতে এবং এটি প্রসারিত করার জন্য প্রয়োগ করা সম্ভব ।

প্রসারণ বিধি

Use            Expansion

Ts...          T1, ..., Tn
Ts&&...        T1&&, ..., Tn&&
x<Ts,Y>::z...  x<T1,Y>::z, ..., x<Tn,Y>::z
x<Ts&,Us>...   x<T1&,U1>, ..., x<Tn&,Un>
func(5,vs)...  func(5,v1), ..., func(5,vn)

বিস্তৃতি ভিতরের দিকে দিকে এগিয়ে যায়। লক-স্টেপে দুটি তালিকা প্রসারিত করার সময়, তাদের একই আকার থাকতে হবে।

আরও উদাহরণ:

gun(A<Ts...>::hun(vs)...);

Tsএর টেম্পলেট আর্গুমেন্ট তালিকায় সমস্তটি প্রসারিত করে Aএবং তারপরে hunসমস্তটির সাথে ফাংশনটি প্রসারিত হয় vs

gun(A<Ts...>::hun(vs...));

সমস্ত Tsটেমপ্লেট আর্গুমেন্ট তালিকায় Aএবং সমস্ত vsফাংশন আর্গুমেন্ট হিসাবে প্রসারিত করে hun

gun(A<Ts>::hun(vs)...);

লক-স্টেপ hunসহ Tsএবং এতে ফাংশনটি প্রসারিত করে vs

বিঃদ্রঃ:

Tsএটি কোনও ধরণের নয় এবং vsএকটি মূল্য নয়! প্রকার / মানগুলির তালিকার জন্য এগুলি পৃথক নাম। হয় তালিকা সম্ভাব্য খালি হতে পারে। উভয়ই কেবল নির্দিষ্ট ক্রিয়া মেনে চলে। সুতরাং নিম্নলিখিতটি সম্ভব নয়:

typedef Ts MyList;  // error!
Ts var;             // error!
auto copy = vs;     // error!

সম্প্রসারণ লোকি

ফাংশন যুক্তি

template <typename... Ts>
void fun(Ts... vs)

প্রারম্ভিক তালিকা

any a[] = { vs... };

বেস নির্দিষ্টকারী

template <typename... Ts>
struct C : Ts... {};
template <typename... Ts>
struct D : Box<Ts>... { /**/ };

সদস্য আরম্ভকারী তালিকা

// Inside struct D
template <typename... Us>
D(Us... vs) : Box<Ts>(vs)... {}

মোক্ষম যুক্তি তালিকাগুলি

std::map<Ts...> m;

যুক্তিগুলির জন্য যদি কোনও সম্ভাব্য ম্যাচ থাকে তবে কেবল সংকলন করবে।

ক্যাপচার তালিকা

template <class... Ts> void fun(Ts... vs) {
    auto g = [&vs...] { return gun(vs...); }
    g();
}

গুণাবলী তালিকা

struct [[ Ts... ]] IAmFromTheFuture {};

এটি স্পেসিফিকেশনে রয়েছে, তবে কোনও বৈশিষ্ট্য নেই যা টাইপ হিসাবে প্রকাশ করা যেতে পারে, এখনও।


ভাল লাগল ফাংশন আর্গুমেন্টগুলি লোকির বাইরে রেখে গেছে, যদিও: পি
পোটোসওয়টার

ধন্যবাদ পোটাটোসওয়াত্টার ফাংশন আর্গুমেন্ট তালিকার বিস্তারের কথা বলা হয়নি।
টাইপ 1232

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