টেমপ্লেট শ্রেণীর সদস্য ফাংশন স্পষ্ট বিশেষীকরণ


88

আমাকে কিছু ধরণের জন্য টেমপ্লেট সদস্য ফাংশন বিশেষজ্ঞ করতে হবে (আসুন ডাবল বলি )। এটি দুর্দান্ত কাজ করে যখন শ্রেণি Xনিজেই কোনও টেম্পলেট শ্রেণি নয়, তবে আমি যখন এটি টেমপ্লেট তৈরি করি তখন জিসিসি সংকলন-সময় ত্রুটিগুলি দেওয়া শুরু করে।

#include <iostream>
#include <cmath>

template <class C> class X
{
public:
   template <class T> void get_as();
};

template <class C>
void X<C>::get_as<double>()
{

}

int main()
{
   X<int> x;
   x.get_as();
}

এখানে ত্রুটি বার্তা

source.cpp:11:27: error: template-id
  'get_as<double>' in declaration of primary template
source.cpp:11:6: error: prototype for
  'void X<C>::get_as()' does not match any in class 'X<C>'
source.cpp:7:35: error: candidate is:
  template<class C> template<class T> void X::get_as()

আমি কীভাবে এটি ঠিক করতে পারি এবং এখানে সমস্যাটি কী?

আগাম ধন্যবাদ.


4
এটি বর্তমান মানদণ্ডে অবৈধ, বিশেষায়িত করার জন্য, আপনাকে
ক্লাসেরও

ক্লাস টেম্পলেট না থাকলে তবে এটি কাজ করে। এটাও কি বেআইনী?
নেতৃত্বকোল

না, এটি পুরোপুরি ঠিক আছে, এটি কেবল শ্রেণির টেম্পলেটগুলির জন্য যা এই নিয়মটি প্রয়োগ করে (এএফএআইকি)।
নিম

উত্তর:


108

এটি সেভাবে কাজ করে না। আপনার নিম্নলিখিতটি বলা দরকার, তবে এটি সঠিক নয়

template <class C> template<>
void X<C>::get_as<double>()
{

}

সুস্পষ্টরূপে বিশেষায়িত সদস্যদের তাদের পার্শ্ববর্তী শ্রেণির টেম্পলেটগুলিও স্পষ্টভাবে স্পেশালিস্ট করার জন্য প্রয়োজন। সুতরাং আপনাকে নিম্নলিখিতটি বলা দরকার যা কেবল সদস্যটির জন্য বিশেষত হবে X<int>

template <> template<>
void X<int>::get_as<double>()
{

}

আপনি যদি আশেপাশের টেমপ্লেটটিকে অনির্দিষ্ট করে রাখতে চান তবে আপনার বেশ কয়েকটি পছন্দ আছে। আমি অতিরিক্ত বোঝা পছন্দ করি

template <class C> class X
{
   template<typename T> struct type { };

public:
   template <class T> void get_as() {
     get_as(type<T>());
   }

private:
   template<typename T> void get_as(type<T>) {

   }

   void get_as(type<double>) {

   }
};

আপনার type<>মোড়কের দরকার কেন ? টাইপের একটি পয়েন্টারটিতে 0 টির একটি কাস্ট Tকি কৌতুক করতে পারে না ? আমি অনুমান করি যে এটি মার্জিত নয় ...
নিম

দেখে মনে হচ্ছে এটি করা সম্ভব নয়। ধন্যবাদ
নেতৃত্বকোল

4
@ নিম, ঠিক আছে, আমি মনে করি পয়েন্টার thingালাই জিনিসটি কুৎসিত, এবং এমন ধরণের জন্য কাজ করবে না যা আপনি পয়েন্টার (রেফারেন্স) এ গঠন করতে পারবেন না। এছাড়াও, একটি ফাংশন প্যারামিটার একটি আকার ছাড়া অ্যারের ধরণের পয়েন্টার হওয়া সি ++ এ অবৈধ। এটি কোনও প্রকারের মোড়কে রাখার ফলে এটি সমস্ত ধরণের কাজ করে।
জোহানেস স্কাউব - 12

4
@ জোহানেস শ্যাব-লিটব: ওভারলোডের পাশাপাশি অন্যান্য পছন্দগুলি কী? তাদের কিছু দেখাতে পারেন?
জিন-বার্নার্ড জানসেন

4
@ ফাস্ট-রিফ্লেক্স তার মন্তব্যটি ব্যবহার template<typename T> void get_as(T*); void get_as(double*);এবং পাস করার জন্য ছিল (T*)0
জোহানেস স্কাউব -

25

যদি কেউ ব্যবহার করতে সক্ষম হয় তবে std::enable_ifআমরা SFINAE এর উপর নির্ভর করতে পারি (প্রতিস্থাপনের ব্যর্থতা কোনও ত্রুটি নয়)

এটি এমনভাবে কাজ করবে ( লাইভ দেখুন ):

#include <iostream>
#include <type_traits>

template <typename C> class X
{
public:
    template <typename T, 
              std::enable_if_t<!std::is_same_v<double,T>, int> = 0> 
    void get_as() { std::cout << "get as T" << std::endl; }

    template <typename T, 
              std::enable_if_t<std::is_same_v<double,T>, int> = 0> 
    void get_as() { std::cout << "get as double" << std::endl; }
};

int main() {
   X<int> d;
   d.get_as<double>();

   return 0;
}

কুরুচিপূর্ণ বিষয়টি হ'ল, এই সমস্ত সক্ষম_এফের সাহায্যে সংকলকের জন্য কেবলমাত্র একটি বিশেষায়িতকরণ পাওয়া দরকার অন্যথায় বিশৃঙ্খলা ত্রুটি দেখা দেবে। কেন ডিফল্ট আচরণ "টি হিসাবে পাবেন" এছাড়াও সক্ষম করার প্রয়োজন হয় তা ঠিক।


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