কেন ফাংশন টেমপ্লেট আংশিকভাবে বিশেষজ্ঞ করা যায় না?


89

আমি জানি ভাষার স্পেসিফিকেশন ফাংশন টেম্পলেটটির আংশিক বিশেষায়িতকরণ নিষিদ্ধ করে ।

আমি যুক্তিটি জানতে চাই কেন এটি এটি নিষেধ করে? এগুলি কি কার্যকর নয়?

template<typename T, typename U> void f() {}   //allowed!
template<> void f<int, char>()            {}   //allowed!
template<typename T> void f<char, T>()    {}   //not allowed!
template<typename T> void f<T, int>()     {}   //not allowed!

জন্য template<typename T, typename U> void f(T t, U u) {}আরো template<> void f(int t, char u) {}অনুমোদিত হয়।
ড্যাশে

10
আমি আকর্ষণীয় মনে করি যে লোকেরা যখন কাজের সমাধান দেয় তবে প্রশ্নটি কীভাবে "আমি কীভাবে একটি অনুরূপ লক্ষ্য অর্জন করতে পারি" না "" এই আচরণের পিছনে যুক্তি কী তা "নয় ... আমি নিজেই এই পছন্দটির কারণটি জানি না, তবে আমি ধরেই নিয়েছি কমিটির অবশ্যই ফাংশন টেম্পলেট আংশিক বিশেষতাকে নিষিদ্ধ করার কারণ থাকতে হবে। এখন পর্যন্ত "নিকটতম" ব্যাখ্যা হ'ল জর্জি পোস্ট করা লিঙ্ক, যা কেবলমাত্র অতিরিক্ত চাপ উপস্থিত থাকলে ফাংশন টেম্পলেট আংশিক বিশেষত্বের সম্ভাব্য "ঝুঁকি" চিহ্নিত করে। তবে, আমি এই বৈশিষ্ট্যটি নিষিদ্ধ করার কারণ মনে করি না, তাই আমি ধরে নিচ্ছি এর আরও কিছু আছে ..
বার্টগল

উত্তর:


59

আফাইক যে সি ++ 0x এ পরিবর্তিত হয়েছে।

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

যদি কোনও থাকে তবে আপনি প্রাসঙ্গিক ডিআর (ত্রুটি প্রতিবেদন) সন্ধান করতে পারেন।

সম্পাদনা : এটি পরীক্ষা করে, আমি দেখতে পেলাম যে অন্যরাও বিশ্বাস করেছে যে, তবে খসড়া স্ট্যান্ডার্ডে কেউ এ জাতীয় সমর্থন খুঁজে পাচ্ছে না। এই SO থ্রেডটি ইঙ্গিত দেয় যে ফাংশন টেম্পলেটগুলির আংশিক বিশেষত্ব C ++ 0x এ সমর্থিত নয়

সম্পাদনা 2 : static"ক্লাসের সদস্য হিসাবে ফাংশন স্থাপন" বলতে আমি কী বোঝাতে চেয়েছি তার একটি উদাহরণ :

#include <iostream>
using namespace std;

// template<typename T, typename U> void f() {}   //allowed!
// template<> void f<int, char>()            {}   //allowed!
// template<typename T> void f<char, T>()    {}   //not allowed!
// template<typename T> void f<T, int>()     {}   //not allowed!

void say( char const s[] ) { std::cout << s << std::endl; }

namespace detail {
    template< class T, class U >
    struct F {
        static void impl() { say( "1. primary template" ); }
    };

    template<>
    struct F<int, char> {
        static void impl() { say( "2. <int, char> explicit specialization" ); }
    };

    template< class T >
    struct F< char, T > {
        static void impl() { say( "3. <char, T> partial specialization" ); }
    };

    template< class T >
    struct F< T, int > {
        static void impl() { say( "4. <T, int> partial specialization" ); }
    };
}  // namespace detail

template< class T, class U >
void f() { detail::F<T, U>::impl(); }    

int main() {
    f<char const*, double>();       // 1
    f<int, char>();                 // 2
    f<char, double>();              // 3
    f<double, int>();               // 4
}

আপনার কি N3225 মান আছে? আমি একটি দ্রুত অনুসন্ধান করেছি কিন্তু এটি খুঁজে পেলাম না: /
ম্যাথিউ এম।

4
আহ দুঃখিত ... একটি শব্দ অনুপস্থিত ছিল। আমার কাছে ডকুমেন্ট আছে তবে নির্দিষ্ট অনুচ্ছেদটি খুঁজে পেলাম না । যদিও আপনার সম্পাদনা দেওয়া হয়েছে, আমি অনুমান করি যে এটি কেবল সেখানে নেই কারণ :)
ম্যাথিউ এম।

4
এটি সি ++ 0x এ পরিবর্তন করা হয়নি। আমি এর ইউটিলিটি সম্পর্কেও সন্দেহ করি। আপনি সর্বদা টেম্পলেটটি ওভারলোড করতে পারেন এবং আংশিক ক্রম ব্যবহার করতে পারেন ।
জোহানেস স্কাউব -

4
দেরীতে আপডেট: আট বছর পরেও সি ++ 17 এ পরিবর্তন হয় নি এবং এটিও সি ++ ২০ এ প্রবেশ করবে বলে মনে হয় না। যদিও এর কোনও কারণ দেখতে পাচ্ছেন না ...
অ্যাকনকাগুয়া

এটি এখন পর্যন্ত ধারণার সর্বাধিক বিস্তৃত বাস্তবায়ন, আমি বিশ্বাস করি
ভিক্টর

19

ভাল, আপনি সত্যিই আংশিক ফাংশন / পদ্ধতি বিশেষীকরণ করতে পারবেন না তবে আপনি ওভারলোডিং করতে পারেন।

template <typename T, typename U>
T fun(U pObj){...}

// acts like partial specialization <T, int> AFAIK 
// (based on Modern C++ Design by Alexandrescu)
template <typename T>
T fun(int pObj){...} 

এটি উপায় তবে এটি আপনাকে সন্তুষ্ট করে কিনা আমি জানি না।


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

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

আমি নিশ্চিত নই যে বৈকল্পিক টেম্পলেটগুলি পাস করার অর্থ কী ছিল, তাই আমি এটি আংশিক বিশেষজ্ঞের থেকে কীভাবে আলাদা তা জানতে চাই। আপনি কি আরও বিশদ সরবরাহ করতে পারেন?
শুরু

আপনি যদি সমস্ত ইন্টিগ্রাল এবং ফ্লোট টাইপের জন্য মাত্র দুটি ফাংশন চান?
দিমিত্রি দোকসিন

15

সাধারণভাবে, ওভারলোডিংয়ের ঝামেলার কারণে ফাংশন টেম্পলেটগুলিকে মোটেও বিশেষায়িত করার পরামর্শ দেওয়া হয় না। এখানে সি / সি ++ ব্যবহারকারী জার্নালের একটি ভাল নিবন্ধ: http://www.gotw.ca/publications/mill17.htm

এবং এটিতে আপনার প্রশ্নের একটি সৎ উত্তর রয়েছে:

একটি জিনিসের জন্য, আপনি আংশিকভাবে এগুলিকে বিশেষীকরণ করতে পারবেন না - ভাষাটি বলে যে আপনি পারবেন না ঠিক এটি কারণ।


4
নিবন্ধটি আংশিক বিশেষায়নের বিষয়ে নয় তবে এটি একবার উল্লেখ করা হয়েছে।
ইউরি পিনহলো 13

11

যেহেতু আপনি আংশিকভাবে ক্লাস বিশেষজ্ঞ করতে পারেন, তাই আপনি একটি ফান্টার ব্যবহার করতে পারেন:

#include <iostream>

template < typename dtype , int k > struct fun
{
 int operator()()
 {
  return k ;
 }
} ;

template < typename dtype > struct fun < dtype , 0 >
{
 int operator()()
 {
  return 42 ;
 }
} ;

int main ( int argc , char * argv[] )
{
 std::cout << fun<float,5>()() << std::endl ;
 std::cout << fun<float,0>()() << std::endl ;
}

4
এরপরে আপনি কলগুলি করার জন্য একক ফাংশন টেম্পলেট ব্যবহার করতে পারেন, কুরুচিপূর্ণ ()()সিনট্যাক্স থেকে মুক্তি পেয়ে ।
tmr232
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.