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


9

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

নিম্নলিখিত উদাহরণ বিবেচনা করুন:

static void test() {}

using FunctionPointer = void(*)();

static constexpr FunctionPointer functions[] = { test };

template <FunctionPointer function>
static void wrapper_function()
{
    function();
}

int main()
{
    test();  // OK
    functions[0]();  // OK

    wrapper_function<test>();  // OK
    wrapper_function<functions[0]>();  // Error?
}

এমএসভিসি কোডটি সংকলন করে তবে ইন্টেলিসেন্স নিম্নলিখিত ত্রুটিটি দেয়:invalid nontype template argument of type "const FunctionPointer"

gcc নিম্নলিখিত বার্তাটি সংকলন করতে ব্যর্থ:

<source>: In function 'int main()':
<source>:19:33: error: no matching function for call to 'wrapper_function<functions[0]>()'
   19 |  wrapper_function<functions[0]>();  // Error?
      |                                 ^
<source>:8:13: note: candidate: 'template<void (* function)()> void wrapper_function()'
    8 | static void wrapper_function()
      |             ^~~~~~~~~~~~~~~~
<source>:8:13: note:   template argument deduction/substitution failed:
<source>:19:30: error: '(FunctionPointer)functions[0]' is not a valid template argument for type 'void (*)()'
   19 |  wrapper_function<functions[0]>();  // Error?
      |                   ~~~~~~~~~~~^
<source>:19:30: note: it must be the address of a function with external linkage

ঝনঝন নিম্নলিখিত বার্তাটি সংকলন করতে ব্যর্থ:

<source>:19:2: error: no matching function for call to 'wrapper_function'
        wrapper_function<functions[0]>();  // Error?
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:8:13: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'function'
static void wrapper_function()
            ^
1 error generated.

প্রশ্নাবলী:

কি wrapper_function<functions[0]>();বৈধ কি না?

যদি তা না হয়, তবে এখানে functions[0]টেমপ্লেট যুক্তি হিসাবে পাস করার মতো আমি কি কিছু করতে পারি wrapper_function? আমার লক্ষ্য বিষয়বস্তু সহ সংকলন সময়ে ফাংশন পয়েন্টারগুলির একটি নতুন অ্যারে তৈরি করা { wrapper_function<functions[0]>, ..., wrapper_function<functions[std::size(functions) - 1]> }


হুঁ এটি আকর্ষণীয়, আমি ভেবেছিলাম সমস্যাটি হ'ল আপনি কোনও ধরণের পরিবর্তে মান (পয়েন্টার) ব্যবহার করছেন। এমনকি wrapper_function<decltype(functions[0])>()সংকলন করে না।
CoryKramer

6
সি ++ 17 তে এখন কাজ করছেন ... এখন স্ট্যান্ডার্ডিজের মধ্যে পার্থক্যটি সন্ধান করতে ...
অ্যান্ডি

উত্তর:


5

wrapper_function<functions[0]>();নিম্নলিখিত কারণে অভিব্যক্তি নিষিদ্ধ:

14.3.2 টেমপ্লেট নন-টাইপ আর্গুমেন্ট [temp.arg.nontype]

অ-টাইপযুক্ত, নন-টেম্পলেট টেম্পলেট-প্যারামিটারের জন্য একটি টেম্পলেট-যুক্তি হতে হবে:

[...]

- একটি ধ্রুবক অভিব্যক্তি (5.19) যা স্থিতিশীল স্টোরেজ> সময়কাল এবং বাহ্যিক বা অভ্যন্তরীণ যোগসূত্র বা ফাংশন টেম্পলেট এবং ফাংশন টেম্পলেট-আইডিসহ বহিরাগত বা অভ্যন্তরীণ লিঙ্কেজ সহ কোনও ফাংশনের ঠিকানা নির্দিষ্ট করে তবে অ স্থিত শ্রেণীর সদস্যদের বাদ দিয়ে প্রকাশ করে (বন্ধনীকে উপেক্ষা করে) & আইডি-এক্সপ্রেশন হিসাবে, নাম বাদে যদি নামটি কোনও ফাংশন বা অ্যারে উল্লেখ করে এবং বাদ দেওয়া যেতে পারে তবে সংশ্লিষ্ট টেম্পলেট-প্যারামিটারটি যদি কোনও রেফারেন্স হয় তবে তা বাদ দেওয়া হবে; [...]

ফর্ম ব্যতীত অন্য ধরণের টেম্পলেট আর্গুমেন্ট হিসাবে পয়েন্টার ব্যবহার নিষিদ্ধ &id, সুতরাং মূলত নিম্নলিখিতটি কাজ করবে:

static void test() {}

using FunctionPointer = void(*)();

static constexpr FunctionPointer functions[] = { test };

template <FunctionPointer function>
static void wrapper_function()
{
    function();
}

int main()
{
    test();  // OK
    functions[0]();  // OK

    wrapper_function<test>();  // OK
    wrapper_function<&test>();  // OK
}

এবং সি ++ 14 বিকল্পের সাথে সংকলিত হওয়ার পরে নিম্নলিখিত স্নিপেট কাজ করবে না:

constexpr auto func = &test;
wrapper_function<func>();

সি ++ 17 বিকল্পের সাথে সংকলিত হয়ে গেলে, আপনার পদ্ধতির এবং উপরেরটি উভয়ই কাজ করবে:

int main()
{
    test();  // OK
    functions[0]();  // OK

    wrapper_function<test>();  // OK
    wrapper_function<&test>();  // OK
    wrapper_function<func>();  // OK

    wrapper_function<functions[0]>();  // OK
}

লাইভ দেখুন


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

সি ++ 17 প্রতিস্থাপন করে এটি একটি " রূপান্তরিত ধ্রুবক অভিব্যক্তি " দিয়ে, অর্থাত্ এটি ধ্রুবক এক্সপ্রেশনগুলি চেইন করতে দেয় তাই wrapper_function<func>()এটিও কাজ করবে।
rustyx

আমি পুরোটা লেখার পরে ঠিক আছে উত্তরটি চেক এবং আপডেট করবে। টিএনএক্স
নটক্র্যাকার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.