স্ট্যান্ড :: জোড় <অটো, অটো> রিটার্ন টাইপ


16

আমি প্রায় খেলে গেল autoমধ্যে std::pair। নীচের কোডে, ফাংশনটি fএমন কোনও std::pairধরণের ফেরত দেওয়ার কথা যা কোনও টেম্পলেট প্যারামিটারের উপর নির্ভর করে।

একটি কার্যকরী উদাহরণ:

উদাহরণ 1

template <unsigned S>
auto f()
{
    if constexpr (S == 1)
        return std::pair{1, 2}; // pair of ints
    else if constexpr (S == 2)
        return std::pair{1.0, 2.0}; // pair of doubles
    else
        return std::pair{0.0f, 0.0f}; // pair of floats
}

এটি জিসিসি 9.2, জিসিসি 10.0, ক্ল্যাং 9.0 এবং ক্ল্যাং 10.0 নিয়ে কাজ করে।

এরপরে, আমি std::pairপরিষ্কারভাবে কারণে রিটার্নের ধরণটি স্পষ্টভাবে লিখতে চেয়েছিলাম :

উদাহরণ 2

template <unsigned S>
std::pair<auto, auto> f()
{
    if constexpr (S == 1)
        return {1, 2};
    /* ... */
}

জিসিসি 9.2 / 10.0 এবং ক্ল্যাং 9.0 / 10.0 উভয়ই এটি সঙ্কলন করতে ব্যর্থ হয়েছিল।

জিসিসি 9.2

error: invalid use of 'auto'
error: template argument 1 is invalid // first argument (auto) of std::pair
error: template argument 2 is invalid // second argument (auto) of std::pair
error: cannot convert '<brace-enclosed initializer list>' to 'int' in return

শেষ ত্রুটি বার্তা থেকে, gcc 9.2 মনে হয় যে std::pair<auto, auto>এটি একটি int। কিভাবে এই ব্যাখ্যা করা যেতে পারে?

জিসিসি 10.0

error: returning initializer list

এই ত্রুটিটি বোধগম্য, তবে আমি নির্মাণকারীকে std::pairআহবান করার প্রত্যাশা করলাম , বা এখানে আমি এখানে কিছু অনুপস্থিত রয়েছি?

ঝনঝন 9.0 এবং 10.0

'auto' not allowed in template argument
excess elements in scalar initializer
no matching function for call to 'f'

ঠিক আছে, ঝনঝন করা এগুলির কোনও পছন্দ করে না। দ্বিতীয় ত্রুটি বার্তা থেকে, মনে হয় যে ঝাঁকুনি বিশ্বাস করে যে রিটার্নের ধরণটি int

অবশেষে, জিসিসি 10.0 এর সাথে সংকলিত প্রাপ্ত ত্রুটিটি ঠিক করার জন্য, আমি std::pairস্পষ্টতই ফিরে আসার সিদ্ধান্ত নিয়েছি :

উদাহরণ 3

template <unsigned S>
std::pair<auto, auto> f()
{
    if constexpr (S == 1)
        return std::pair{1, 2};
    /* ... */
}

ঝনঝন 9.0 এবং 10.0

আগের মত একই, তবে অতিরিক্ত সহ:

no viable conversion from returned value of type 'std::pair<int, int>' to function return type 'int'

এখানে ঝনঝনানি এখনও মনে করে আমরা একটি ফিরে আসছি int?

জিসিসি 9.2

পূর্বের মত.

জিসিসি 10.0

এটি কাজ করে!

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

উত্তর:


23

বাক্য গঠন:

std::pair<auto, auto> f() { return std::pair(1, 2); }
~~~~~~~~~~~~~~~~~~~~~

মূল ধারণা টিএস এর অংশ ছিল কিন্তু কনসেপ্ট প্রস্তাবগুলিতে অন্তর্ভুক্ত ছিল না যা সি ++ 20 এর অংশ। যেমন, সি ++ ২০ এ কেবলমাত্র স্থানধারকগুলি auto(এবং এর মত তারতম্যগুলি auto**) decltype(auto), এবং সীমাবদ্ধ স্থানধারক ( Concept autoএবং এর প্রকরণগুলি)। এই ধরণের নেস্টেড স্থানধারক প্রকারটি খুব কার্যকর হবে তবে এটি সি ++ ২০ এর অংশ নয়, সুতরাং সেই ফাংশন ঘোষণাটি খারাপ-গঠন।

এখন, গিসি এটির অনুমতি দেয় কারণ জিসিসি কনসেপ্ট টিএস বাস্তবায়িত করেছে এবং আমার ধারণা তারা এই বৈশিষ্ট্যটি রাখার সিদ্ধান্ত নিয়েছে। ঝনঝন কখনও টিএস প্রয়োগ করেনি, তাই এটি করে না।

যেভাবেই হোক না কেন:

std::pair<auto, auto> f() { return {1, 2}; }

সর্বদা অগঠিত হবে। বাক্যবিন্যাসের অর্থ হ'ল আমরা রিটার্নের ধরণটি হ্রাস করি এবং তারপরে এটি pair<T, U>কোনও প্রকারের সাথে মেলে Tএবং প্রয়োজন U। আমরা মূলত উদ্ভাবিত ফাংশনটি চালু করার চেষ্টা করছি:

template <typename T, typename U>
void __f(std::pair<T, U>);

__f({1, 2}); // this must succeed

তবে আপনি কোনও ধরণের থেকে অনুমান করতে পারবেন না {1, 2}- একটি ব্রেসড-আর-তালিকাতে কোনও প্রকার নেই। সম্ভবত এটি এমন একটি বিষয় যা অন্বেষণ করা উচিত (যেমন এটি একটি সহজ ক্ষেত্রে অন্তত বোঝা সহজ) তবে এটি কখনও অনুমোদিত হয় নি। সুতরাং এটি প্রত্যাখ্যান উভয় উপায়েই সঠিক।

সর্বশেষে:

জিসিসি 9.2 মনে হয় std::pair<auto, auto>এটি একটি int। কিভাবে এই ব্যাখ্যা করা যেতে পারে?

কোনও কারণে (সম্ভবত অন্তর্ভুক্ত সহ আমাদের সি উত্তরাধিকারের কারণে int), যখন জিসিসি কোনও প্রকারটি সনাক্ত বা বুঝতে না পারে তখন এটি intত্রুটি বার্তাগুলিতে স্থানধারক হিসাবে ব্যবহার করে। এটি অত্যন্ত বিভ্রান্তিকর, কারণ স্পষ্টতই এটি জিসিসি, intযা উত্স কোডটি নিয়ে আসে। তবে সেভাবেই।


"ব্র্যাসেড-আরআই-তালিকার কোনও ধরণের আর্গুমেন্ট নেই" আমার কাছে পরিষ্কার নয়। স্টাড :: জোড় <int, int> f () {ফেরত {1,2}; work কাজ করে এবং {1,2 no এর কোনও প্রকার নেই (এটি স্ট্যান্ড :: জোড় <<<, int> এর নির্মাতাকে যেমন আমি বুঝতে পেরেছি তাই অনুরোধ করে)। সম্ভবত <অটো, অটো> দিয়ে, সংকলক প্রাথমিকের তালিকায়, 1, 2} 1 এবং 2 এর প্রকারগুলি কমাতে পারে না?
এমএফএনএক্স

@ এমএফএনএক্সের কোনও টাইপ আর্গুমেন্ট নেই , কেবল টাইপ নেই। ব্রেসড init তালিকা কেবল নির্দিষ্ট পরিস্থিতিতে ব্যবহার করা যেতে পারে - যেমন একটি পরিচিত ধরণের সূচনা করার মতো। তবে সেগুলি ছাড়ের ক্ষেত্রে ব্যবহার করা যাবে না - কারণ তাদের কোনও প্রকার নেই। auto x = {1, 2};কাজ ব্যতীত , তবে সমস্ত ধরণের একই থাকলে কেবল।
ব্যারি

2
বেশিরভাগ সংকলক, প্রথম ত্রুটিতে থামার পরিবর্তে এ থেকে পুনরুদ্ধার করার চেষ্টা করুন যাতে তারা অতিরিক্ত ত্রুটিগুলি রিপোর্ট করতে পারে। এর অর্থ সাধারণত অনুমান করা যায় যে অপরিবর্তনযোগ্য সবকিছুই একটি int। এটি intত্রুটি বার্তাগুলিতে স্থানধারক নয় ; সংকলকটি সত্যিই মনে করে যে এটি একটি int। (এই বিষয়টিকে আরও পরিষ্কার করার জন্য, জিসিসি সম্ভবত কোনও সময়ে "ইনটামিং ইনট" বলেছিল should)
রেমন্ড চেন

2
নোট করুন যে এক্সটেনশনের জন্য আরেকটি সম্ভাব্য অ্যাভিনিউ হ'ল std::pair __f{1,2};কাজ থেকে রিটার্নের ধরণের জন্য ক্লাস টেম্পলেট যুক্তি ছাড়ের অনুমতি দেওয়া হবে ।
ডেভিস হেরিং

2
@ ডেভিস হেরিং আমি সত্যিই std::optional f() { return 4; }কাজ করতে চাই না ।
ব্যারি 16
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.