আমি কীভাবে একটি সি ++ অ্যাপ্লিকেশনটির প্রতিচ্ছবি যুক্ত করতে পারি?


263

আমি এর নাম, বিষয়বস্তু (অর্থাত্ সদস্য এবং তাদের ধরণের) ইত্যাদির জন্য একটি সি ++ শ্রেণি অন্তর্নির্ধারণ করতে সক্ষম হতে চাই I'm আমি এখানে স্থানীয় সি ++ কথা বলছি, পরিচালিত সি ++ নেই, যার প্রতিফলন রয়েছে। আমি বুঝতে পারি যে সিটি+ আরটিটিআই ব্যবহার করে কিছু সীমিত তথ্য সরবরাহ করে। কোন অতিরিক্ত লাইব্রেরি (বা অন্যান্য কৌশল) এই তথ্য সরবরাহ করতে পারে?


18
দুর্ভাগ্যক্রমে, আপনি ম্যাক্রো এবং অন্যান্য প্রিপ্রোসেসিং ছাড়া এটি করতে পারবেন না, কারণ আপনি যদি ম্যাক্রোটিকে কিছু ম্যাক্রো প্রিপ্রোসেসিং যাদু দ্বারা ম্যানুয়ালি তৈরি না করেন তবে প্রয়োজনীয় মেটাডেটার অস্তিত্ব নেই
জাল্ফ

6
আরটিটিআই থেকে আপনি যে তথ্য ফিরে পেতে পারেন সেগুলি বেশিরভাগ ক্ষেত্রেই আপনি বাস্তবে প্রতিচ্ছবি চাইলেও যথেষ্ট নয় enough উদাহরণস্বরূপ আপনি কোনও শ্রেণীর সদস্য ফাংশনগুলি নিয়ে পুনরাবৃত্তি করতে পারবেন না।
জোসেফ গারভিন

উত্তর:


260

আপনাকে যা করতে হবে তা হল ক্ষেত্রগুলি সম্পর্কে প্রতিস্থাপনের ডেটা তৈরি করা। এই ডেটা নেস্টেড ক্লাস হিসাবে সংরক্ষণ করা যেতে পারে।

প্রথমত, প্রিপ্রোসেসরে এটি লিখতে আরও সহজ এবং পরিষ্কার করার জন্য আমরা টাইপড এক্সপ্রেশন ব্যবহার করব। একটি টাইপযুক্ত এক্সপ্রেশন হ'ল একটি অভিব্যক্তি যা বন্ধনীতে টাইপ করে। সুতরাং লেখার পরিবর্তে int xআপনি লিখবেন (int) x। টাইপযুক্ত অভিব্যক্তিগুলিতে সহায়তা করার জন্য এখানে কয়েকটি হ্যান্ডি ম্যাক্রো রয়েছে:

#define REM(...) __VA_ARGS__
#define EAT(...)

// Retrieve the type
#define TYPEOF(x) DETAIL_TYPEOF(DETAIL_TYPEOF_PROBE x,)
#define DETAIL_TYPEOF(...) DETAIL_TYPEOF_HEAD(__VA_ARGS__)
#define DETAIL_TYPEOF_HEAD(x, ...) REM x
#define DETAIL_TYPEOF_PROBE(...) (__VA_ARGS__),
// Strip off the type
#define STRIP(x) EAT x
// Show the type without parenthesis
#define PAIR(x) REM x

এরপরে, আমরা REFLECTABLEপ্রতিটি ক্ষেত্রের ডেটা তৈরি করতে ম্যাক্রো সংজ্ঞায়িত করি (ক্ষেত্রটি নিজেই)। এই ম্যাক্রোটিকে এভাবে বলা হবে:

REFLECTABLE
(
    (const char *) name,
    (int) age
)

সুতরাং বুস্ট.পিপি ব্যবহার করে আমরা প্রতিটি যুক্তির মাধ্যমে পুনরাবৃত্তি করি এবং এর মতো ডেটা উত্পন্ন করি:

// A helper metafunction for adding const to a type
template<class M, class T>
struct make_const
{
    typedef T type;
};

template<class M, class T>
struct make_const<const M, T>
{
    typedef typename boost::add_const<T>::type type;
};


#define REFLECTABLE(...) \
static const int fields_n = BOOST_PP_VARIADIC_SIZE(__VA_ARGS__); \
friend struct reflector; \
template<int N, class Self> \
struct field_data {}; \
BOOST_PP_SEQ_FOR_EACH_I(REFLECT_EACH, data, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))

#define REFLECT_EACH(r, data, i, x) \
PAIR(x); \
template<class Self> \
struct field_data<i, Self> \
{ \
    Self & self; \
    field_data(Self & self) : self(self) {} \
    \
    typename make_const<Self, TYPEOF(x)>::type & get() \
    { \
        return self.STRIP(x); \
    }\
    typename boost::add_const<TYPEOF(x)>::type & get() const \
    { \
        return self.STRIP(x); \
    }\
    const char * name() const \
    {\
        return BOOST_PP_STRINGIZE(STRIP(x)); \
    } \
}; \

এটি যা করে তা ধ্রুবক উত্পন্ন করে যা fields_nক্লাসে প্রতিফলনযোগ্য ক্ষেত্রগুলির সংখ্যা। তারপরে এটি field_dataপ্রতিটি ক্ষেত্রের জন্য বিশেষত্ব দেয় । এটি ক্লাসকেও বন্ধু করে reflector, এটি ক্ষেত্রগুলিতে ব্যক্তিগত থাকা সত্ত্বেও এটি অ্যাক্সেস করতে পারে:

struct reflector
{
    //Get field_data at index N
    template<int N, class T>
    static typename T::template field_data<N, T> get_field_data(T& x)
    {
        return typename T::template field_data<N, T>(x);
    }

    // Get the number of fields
    template<class T>
    struct fields
    {
        static const int n = T::fields_n;
    };
};

ক্ষেত্রগুলির উপর পুনরাবৃত্তি করতে আমরা দর্শনার্থীর প্যাটার্নটি ব্যবহার করি। আমরা ক্ষেত্রের সংখ্যা থেকে শুরু করে এমপিএল পরিসীমা তৈরি করি এবং সেই সূচীতে ক্ষেত্রের ডেটা অ্যাক্সেস করি। তারপরে এটি ব্যবহারকারী-প্রদত্ত দর্শনার্থীর জন্য ক্ষেত্রের ডেটা প্রেরণ করে:

struct field_visitor
{
    template<class C, class Visitor, class I>
    void operator()(C& c, Visitor v, I)
    {
        v(reflector::get_field_data<I::value>(c));
    }
};


template<class C, class Visitor>
void visit_each(C & c, Visitor v)
{
    typedef boost::mpl::range_c<int,0,reflector::fields<C>::n> range;
    boost::mpl::for_each<range>(boost::bind<void>(field_visitor(), boost::ref(c), v, _1));
}

সত্যের মুহুর্তের জন্য আমরা এখন এটি একসাথে রেখেছি। Personপ্রতিবিম্বিত এমন একটি শ্রেণি আমরা এখানে কীভাবে সংজ্ঞায়িত করতে পারি :

struct Person
{
    Person(const char *name, int age)
        :
        name(name),
        age(age)
    {
    }
private:
    REFLECTABLE
    (
        (const char *) name,
        (int) age
    )
};

print_fieldsক্ষেত্রগুলির উপর পুনরাবৃত্তি করতে প্রতিফলনের ডেটা ব্যবহার করে এখানে একটি সাধারণ ফাংশন দেওয়া হয়েছে:

struct print_visitor
{
    template<class FieldData>
    void operator()(FieldData f)
    {
        std::cout << f.name() << "=" << f.get() << std::endl;
    }
};

template<class T>
void print_fields(T & x)
{
    visit_each(x, print_visitor());
}

print_fieldsপ্রতিফলনযোগ্য Personশ্রেণীর সাথে ব্যবহারের একটি উদাহরণ :

int main()
{
    Person p("Tom", 82);
    print_fields(p);
    return 0;
}

কোন ফলাফল:

name=Tom
age=82

এবং ভয়েলা, আমরা 100 টি কোডের নীচে সি ++ এ সবে প্রতিবিম্ব প্রয়োগ করেছি।


106
প্রতিস্থাপন কীভাবে কার্যকর করা যায় তা প্রদর্শনের জন্য কুডোস, এটি করা যায় না বলে। এটি এর মতো উত্তর যা এসওকে একটি দুর্দান্ত সংস্থান করে।
fearless_fool

4
নোট করুন যে আপনি ভিজ্যুয়াল স্টুডিওতে এটি সংকলন করার চেষ্টা করলে আপনি একটি ত্রুটি পাবেন কারণ ভিএস ভেরিয়েডিক ম্যাক্রো প্রসারণটি সঠিকভাবে পরিচালনা করে না। ভিএস এর জন্য, যুক্ত করার চেষ্টা করুন #define DETAIL_TYPEOF_INT2(tuple) DETAIL_TYPEOF_HEAD tupleএবং #define DETAIL_TYPEOF_INT(...) DETAIL_TYPEOF_INT2((__VA_ARGS__)) এবং টিওয়াইপিওএফ (এক্স) এর সংজ্ঞাটি এতে পরিবর্তন করুন:#define TYPEOF(x) DETAIL_TYPEOF_INT(DETAIL_TYPEOF_PROBE x,)
ফেংলেই কাই

আমি ত্রুটি পেয়েছি 'BOOST_PP_IIF_0' কোনও প্রকারের নাম দেয় না। আপনি দয়া করে সাহায্য করতে পারেন।
অঙ্কিত জালানী

3
আমার নিজের উত্তর দেখুন - stackoverflow.com/a/28399807/2338477 আমি নিষ্কাশিত এবং সমস্ত সংজ্ঞায়িত repacked করেছি, এবং বুস্ট গ্রন্থাগার প্রয়োজন হয় না। ডেমো কোড হিসাবে আমি এক্সএমএলকে সিরিয়ালাইজেশন সরবরাহ করছি এবং এক্সএমএল থেকে পুনরুদ্ধার করছি।
টারমোপিকারো

107

reflectionচারিদিকে দুই প্রকার সাঁতার কাটছে।

  1. কোনও ধরণের সদস্যদের উপর পুনরাবৃত্তি করে, এর পদ্ধতিগুলি গণ্য করে ইত্যাদি Insp

    সি ++ দিয়ে এটি সম্ভব নয়।
  2. শ্রেণি-ধরণের (শ্রেণি, কাঠামো, ইউনিয়ন) কোনও পদ্ধতি বা নেস্টেড টাইপ আছে কিনা তা পরীক্ষা করে পরিদর্শন করে অন্য একটি বিশেষ ধরণের থেকে প্রাপ্ত।

    C ++ ব্যবহার করে এই ধরণের জিনিস সম্ভব template-tricksboost::type_traitsঅনেক কিছুর জন্য ব্যবহার করুন (যেমন কোনও ধরণের অবিচ্ছেদ্য কিনা তা পরীক্ষা করা)। সদস্য ফাংশনের উপস্থিতি যাচাইয়ের জন্য, ব্যবহার করুন কোনও ফাংশনের অস্তিত্ব পরীক্ষা করার জন্য কোনও টেম্পলেট লেখা সম্ভব? । নির্দিষ্ট নেস্টেড ধরণের উপস্থিত রয়েছে কিনা তা যাচাই করার জন্য, সরল SFINAE ব্যবহার করুন ।

যদি আপনি বরং 1 টি সম্পন্ন করার উপায়গুলি খুঁজছেন) যেমন শ্রেণীর কতগুলি পদ্ধতি রয়েছে তা দেখার মতো, বা শ্রেণীর আইডির স্ট্রিং উপস্থাপনা পাওয়ার মতো, তবে আমি ভয় করি যে এটি করার কোনও স্ট্যান্ডার্ড সি ++ উপায় নেই। আপনি ব্যবহার করতে হবে

  • কিউটি মেটা অবজেক্ট কমপাইলারের মতো একটি মেটা সংকলক যা আপনার কোডের অতিরিক্ত মেটা তথ্য যুক্ত করে অনুবাদ করে।
  • ম্যাক্রোগুলি সমন্বিত একটি ফ্রেমওয়ার্ক যা আপনাকে প্রয়োজনীয় মেটা-তথ্য যুক্ত করতে দেয়। আপনাকে কাঠামোটি সমস্ত পদ্ধতি, শ্রেণি-নাম, বেস-শ্রেণি এবং এটির যা প্রয়োজন তা বলা দরকার।

সি ++ গতির কথা মাথায় রেখে তৈরি করা হয়েছে। আপনি যদি সি # বা জাভার মতো উচ্চ-স্তরের পরিদর্শন চান, তবে আমি ভয় পাচ্ছি যে আপনাকে কোনও প্রচেষ্টা ছাড়া কোনও উপায় নেই বলে দিতে হবে।


122
সি ++ মনের গতিতে তৈরি করা হয়েছে, তবে দর্শনটি "যত দ্রুত সম্ভব" নয়, এর পরিবর্তে এটি "আপনি যদি এটি ব্যবহার না করেন তবে আপনি তার জন্য অর্থ প্রদান করেন না pay" আমি বিশ্বাস করি যে কোনও ভাষার পক্ষে অন্তর্ভুক্তিটি এমনভাবে প্রয়োগ করা সম্ভব যেভাবে এই দর্শনের সাথে মানানসই, সি ++ এর অভাব রয়েছে।
জোসেফ গারভিন

8
@ জোসেফ: এটি কীভাবে করা উচিত? এটি মেটাডেটা সংরক্ষণ করার জন্য সমস্ত প্রয়োজন। যার অর্থ আপনি এটি ব্যবহার না করেও আপনাকে এর জন্য অর্থ প্রদান করতে হবে। (যদি না আপনি পৃথক
প্রকারকে

25
@ জালফ: কেবলমাত্র মেটাডেটা যা দরকার হতে পারে। আমরা যদি কেবল সংকলন-সময়ের প্রতিবিম্ব বিবেচনা করি তবে এটি তুচ্ছ। উদাহরণস্বরূপ একটি সংকলন-সময় ফাংশন members<T>যা টি এর সমস্ত সদস্যের একটি তালিকা ফেরত দেয় আমরা যদি রানটাইম প্রতিবিম্ব (যেমন প্রতিচ্ছবিতে আরটিটিআই মিশ্রিত) পেতে চাইতাম তবে সংকলকটি এখনও সমস্ত প্রতিবিম্বিত বেসের প্রকারগুলি জানতে পারে। এটি সম্ভবত members<T>(T&)কখনই টি = স্টাড :: স্ট্রিংয়ের জন্য ইনস্ট্যান্ট করা হবে না, সুতরাং স্টাড :: স্ট্রিংয়ের জন্য আরটিআইটি বা এর উত্পন্ন শ্রেণিগুলির অন্তর্ভুক্ত করার দরকার নেই।
এমসাল্টারস

9
রিফ্লেক্স লাইব্রেরি (নীচে উল্লিখিত) এখানে বিদ্যমান কোডটি ধীর না করে সি ++ তে প্রতিবিম্ব যুক্ত করেছে: root.cern.ch/drupal/content/reflex
জোসেফ লিসি

6
@ জো: প্রতিবিম্ব কখনই বিদ্যমান কোডকে ধীর করে না। এটি কেবল বিতরণ করা জিনিসকে আরও বড় করে তোলে (যেহেতু আপনাকে কোনও টাইপ তথ্য ডাটাবেস সরবরাহ করতে হবে ...)।
মিমি মিম মিমি

57

এবং আমি একটি পনি পছন্দ করব, কিন্তু পনিগুলি নিখরচায় নয়। :-p

http://en.wikibooks.org/wiki/C%2B%2B_Pramramming/RTTI আপনি যা পেতে চলেছেন তা। আপনি যেমন ভাবছেন তার প্রতিচ্ছবি - রানটাইমে সম্পূর্ণ বর্ণনামূলক মেটাডেটা উপলভ্য - কেবলমাত্র সি ++ এর জন্য ডিফল্টরূপে বিদ্যমান নেই।


1
আমি দ্বিতীয় ব্র্যাড। সি ++ টেমপ্লেটগুলি বরং শক্তিশালী হতে পারে এবং বিভিন্ন 'প্রতিবিম্ব' ধরণের আচরণের আশেপাশের অভিজ্ঞতা রয়েছে, যেমন 'যে কোনও' লাইব্রেরি, টাইপ বৈশিষ্ট্য, সি ++ আরটিটিআই ইত্যাদির প্রতিশ্রুতি দিয়ে সমাধান করা সমস্যার সমাধান করতে পারে at তো নিক, এখানে আপনার লক্ষ্য কী?
হারুন

7
পোনির মন্তব্যে উজ্জীবিত! আমি দু'বার উপস্থাপন করব, কারণ আপনার উত্তরটিও এটির প্রাপ্য, তবে দুঃখের সাথে আমি কেবল একটি পেয়েছি, তাই পনিরা জিতেছে। :-)
ফ্রেঞ্চি পেনভ

6
কেন এটি চতুর প্রতিক্রিয়া তা আমি সত্যিই পাই না। আমি ইতিমধ্যে বলেছি যে এটি প্রয়োগের জন্য আমি লাইব্রেরি ইত্যাদির উল্লেখ চাই। বিভিন্ন সিস্টেমের স্ক্রিপ্ট অ্যাক্সেস, সিরিয়ালাইজেশন ইত্যাদির মঞ্জুরি দেওয়ার জন্য প্রতিচ্ছবি / অন্তঃসন্ধিকরণটি হল
নিক

3
@ নিক: তিনি এরই মধ্যে উত্তর দিয়েছেন। এটি করা যায় না, ডেটার অস্তিত্ব নেই এবং তাই কোনও গ্রন্থাগার এটি আপনার জন্য কার্যকর করতে সক্ষম নয়।
জলফ

@ জাল্ফ এখনও আমার জন্য অদ্ভুতরূপে প্রোগ্রামিং জগতের লোকদের বলেছিলেন যে 'এটি সম্ভব নয়' এবং 'কীভাবে হয় তা আমি জানি না' বলে মনে করে thinks নিশ্চিত যে মেটাডেটা বিদ্যমান নেই তবে ম্যাক্রোগুলির
সাহায্যে beোকানো

39

তথ্য বিদ্যমান রয়েছে - তবে আপনার প্রয়োজনীয় ফর্ম্যাটে নয় এবং কেবল যদি আপনি আপনার ক্লাসগুলি রফতানি করেন। এটি উইন্ডোজে কাজ করে, আমি অন্য প্ল্যাটফর্মগুলি সম্পর্কে জানি না। যেমন হিসাবে স্টোরেজ-শ্রেণীর নির্দিষ্টকরণ ব্যবহার করে:

class __declspec(export) MyClass
{
public:
    void Foo(float x);
}

এটি সংকলকটি ডিএলএল / এক্সে ক্লাস সংজ্ঞা ডেটা তৈরি করে। তবে এটি এমন বিন্যাসে নয় যা আপনি সহজেই প্রতিবিম্বের জন্য ব্যবহার করতে পারেন।

আমার সংস্থায় আমরা একটি লাইব্রেরি তৈরি করেছি যা এই মেটাডেটার ব্যাখ্যা করে এবং ক্লাসে অতিরিক্ত ম্যাক্রো ইত্যাদি etc.ুকিয়ে না দিয়ে আপনাকে কোনও শ্রেণীর প্রতিফলন করতে দেয়। এটি ফাংশনগুলি নীচে কল করার অনুমতি দেয়:

MyClass *instance_ptr=new MyClass;
GetClass("MyClass")->GetFunction("Foo")->Invoke(instance_ptr,1.331);

এটি কার্যকরভাবে করে:

instance_ptr->Foo(1.331);

ইনভোক (এই_পয়েন্টার, ...) ফাংশনে ভেরিয়েবল আর্গুমেন্ট রয়েছে। স্পষ্টতই এইভাবে কোনও ফাংশন কল করে আপনি কনস্ট-সেফটি ইত্যাদির মতো জিনিসগুলিকে ঘৃণা করছেন, তাই এই দিকগুলি রানটাইম চেক হিসাবে প্রয়োগ করা হয়।

আমি নিশ্চিত সিনট্যাক্সটি উন্নত করা যেতে পারে এবং এটি এখন পর্যন্ত কেবল উইন 32 এবং উইন 64 এ কাজ করে। আমরা ক্লাসগুলিতে স্বয়ংক্রিয় জিইউআই ইন্টারফেস থাকার জন্য, সি ++ তে বৈশিষ্ট্য তৈরি করা, এক্সএমএল থেকে এবং এর বাইরে স্ট্রিমিং করার জন্য এটি সত্যিই দরকারী বলে খুঁজে পেয়েছি এবং নির্দিষ্ট বেস বর্গ থেকে বের করার দরকার নেই। যদি পর্যাপ্ত চাহিদা থাকে তবে আমরা এটিকে মুক্তির জন্য আকার দিতে পারি।


1
আমি মনে করি আপনি বোঝাতে চাইছেন __declspec(dllexport)এবং আপনি যদি বিল্ড চলাকালীন এমনটি সক্ষম করে থাকেন তবে .map ফাইল থেকে তথ্যটি পুনরুদ্ধার করতে পারেন।
অরওয়োফিল

17

প্রতিচ্ছবি বক্সের বাইরে সি ++ দ্বারা সমর্থিত নয়। এটি দুঃখজনক কারণ এটি একটি ব্যথার প্রতিরক্ষামূলক পরীক্ষা করে তোলে।

প্রতিবিম্ব করার জন্য বিভিন্ন পন্থা রয়েছে:

  1. ডিবাগ তথ্য (অ পোর্টেবল) ব্যবহার করুন।
  2. আপনার কোডটি ম্যাক্রোর / টেম্পলেটগুলি বা অন্য কোনও উত্সের পদ্ধতির সাথে ছিটিয়ে দিন (কুরুচিপূর্ণ দেখাচ্ছে)
  3. একটি ডেটাবেস তৈরি করতে ক্ল্যাং / জিসিসি এর মতো একটি সংকলক পরিবর্তন করুন।
  4. Qt moc পদ্ধতির ব্যবহার করুন
  5. বুস্ট প্রতিবিম্ব
  6. যথাযথ এবং সমতল প্রতিবিম্ব

প্রথম লিঙ্কটি সর্বাধিক প্রতিশ্রুতিবদ্ধ দেখায় (মোডের ঝাঁকুনি ব্যবহার করে), দ্বিতীয়টি বিভিন্ন কৌশল নিয়ে আলোচনা করে, তৃতীয়টি জিসিসি ব্যবহার করে একটি পৃথক পদ্ধতি:

  1. http://www.donw.org/rfl/

  2. https://bitbucket.org/dwilliamson/clreflect

  3. https://root.cern.ch/how/how-use-reflex

সি ++ প্রতিবিম্বের জন্য এখন একটি ওয়ার্কিং গ্রুপ রয়েছে। সি ++ 14 @ সিইআরএন-এর জন্য সংবাদ দেখুন:

13/08/17 সম্পাদনা করুন:

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

  1. সংক্ষেপে স্থির প্রতিবিম্ব
  2. স্থির প্রতিবিম্ব
  3. স্থির প্রতিবিম্ব জন্য একটি নকশা

তবে এটি অদূর ভবিষ্যতে সি ++ তে একটি প্রমিত প্রতিবিম্ব পদ্ধতির প্রতিশ্রুতিবদ্ধ বলে মনে হচ্ছে না যদি না সি ++ তে প্রতিবিম্বের পক্ষে জনগোষ্ঠীর পক্ষ থেকে আরও অনেক আগ্রহ দেখা যায়।

সর্বশেষ সি ++ স্ট্যান্ডার্ডের সভা থেকে প্রাপ্ত প্রতিক্রিয়ার ভিত্তিতে নিম্নলিখিত স্থিতির বিবরণ দেওয়া হয়েছে:

13/12/2017 সম্পাদনা করুন

প্রতিচ্ছবি C ++ 20 বা আরও সম্ভবত একটি টিএসআরের দিকে অগ্রসর হচ্ছে বলে মনে হচ্ছে। চলাচল যদিও ধীর।

15/09/2018 সম্পাদনা করুন

জাতীয় সংসদে ব্যালটের জন্য একটি খসড়া টিএস পাঠানো হয়েছে।

পাঠ্যটি এখানে পাওয়া যাবে: https://github.com/cplusplus/reflection-ts

11/07/2019 সম্পাদনা করুন

প্রতিচ্ছবি টিএস বৈশিষ্ট্য সম্পূর্ণ এবং গ্রীষ্মে (2019) মন্তব্য এবং ভোট দেওয়ার জন্য বাইরে।

মেটা-টেমপ্লেট প্রোগ্রামিং পদ্ধতির একটি সহজ সংকলন টাইম কোড পদ্ধতির (টিএস-তে প্রতিফলিত হয় না) দিয়ে প্রতিস্থাপন করতে হবে।

10/02/2020 সম্পাদনা করুন

ভিজ্যুয়াল স্টুডিওতে প্রতিচ্ছবি টিএসকে সমর্থন করার জন্য এখানে একটি অনুরোধ রয়েছে:

লেখক ডেভিড সানকেলের টিএস-তে কথা বলুন:

1720 মার্চ 2020 সম্পাদনা করুন

প্রতিবিম্ব বিষয়ে অগ্রগতি হচ্ছে। '2020-02 প্রাগ আইএসও সি ++ কমিটি ট্রিপ রিপোর্ট' থেকে একটি প্রতিবেদন এখানে পাওয়া যাবে:

সি ++ ২৩ এর জন্য যা বিবেচনা করা হচ্ছে তার বিশদ এখানে পাওয়া যাবে (প্রতিবিম্বের সংক্ষিপ্ত বিভাগ অন্তর্ভুক্ত):

2020 সালের 4 ই জুন সম্পাদনা করুন

জেফ প্রেসিং 'প্লাইউড' নামে একটি নতুন কাঠামো প্রকাশ করেছে যাতে রানটাইমের প্রতিবিম্বের জন্য একটি প্রক্রিয়া রয়েছে। আরো বিস্তারিত এখানে পাওয়া যাবে:

এখনও অবধি ব্যবহার করা সর্বাধিক পালিশ এবং সহজ বলে মনে হচ্ছে সরঞ্জামগুলি এবং পদ্ধতির কাছে।


1
সেরন লিঙ্কটি নষ্ট হয়ে গেছে।
মোস্তোভস্কি

cern লিঙ্কগুলি এখনই ঠিক করা উচিত। এগুলি বেশ ঘন ঘন ভাঙ্গার প্রবণতা যা একটি ব্যথা।
দামিয়ান ডিকসন

এই উত্তরটি কি কেবল সংকলন-সময়ের প্রতিবিম্ব বিবেচনা করে?
einpoklum

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

@ ডামিয়ানডিকসন: এটি সত্য নয়। বেশ কয়েকটি রান-টাইম রিফ্লেকশন লাইব্রেরি রয়েছে। এখন, মঞ্জুর করা হয়েছে, তারা বরং চতুর এবং তারা হয় অপ্ট-ইন বা সংকলক নোডফিকেশনগুলির প্রয়োজন, তবে তারা এখনও বিদ্যমান। যদি আমি আপনার মন্তব্যটি বুঝতে পারি তবে আপনি কেবল সংকলন-সময়ের প্রতিচ্ছবি হিসাবে উল্লেখ করেছেন, দয়া করে আপনার উত্তরটি আরও পরিষ্কার করার জন্য সম্পাদনা করুন।
einpoklum

15

আপনি যা করতে চাইছেন তা আপনাকে দেখতে হবে এবং আরটিটিআই আপনার প্রয়োজনীয়তা পূরণ করবে কিনা। আমি কিছু খুব নির্দিষ্ট উদ্দেশ্যে আমার নিজস্ব ছদ্ম-প্রতিবিম্ব বাস্তবায়ন করেছি। উদাহরণস্বরূপ, আমি একবার একটি সিমুলেশন কি আউটপুট হবে নমনীয়ভাবে কনফিগার করতে সক্ষম হতে চেয়েছিলেন। এটির জন্য ক্লাসে কিছু বয়লারপ্লিট কোড যুক্ত করা দরকার যা আউটপুট হবে:

namespace {
  static bool b2 = Filter::Filterable<const MyObj>::Register("MyObject");
} 

bool MyObj::BuildMap()
{
  Filterable<const OutputDisease>::AddAccess("time", &MyObj::time);
  Filterable<const OutputDisease>::AddAccess("person", &MyObj::id);
  return true;
}

প্রথম কলটি ফিল্টারিং সিস্টেমে এই অবজেক্টটিকে যুক্ত করে, যা BuildMap()কোন পদ্ধতি উপলভ্য তা নির্ধারণের জন্য পদ্ধতিটিকে কল করে ।

তারপরে, কনফিগ ফাইলে আপনি এই জাতীয় কিছু করতে পারেন:

FILTER-OUTPUT-OBJECT   MyObject
FILTER-OUTPUT-FILENAME file.txt
FILTER-CLAUSE-1        person == 1773
FILTER-CLAUSE-2        time > 2000

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


এই ফাংশনগুলি সবসময় সত্য প্রত্যাবর্তন করতে হবে;) আমি ধরে নিই যে এটি স্ট্যাটিক থ্রি অর্ডার দেওয়ার সমস্যাগুলি থেকে সুরক্ষিত?
পলম

14

আমি কিউটি ব্যবহার করার পরামর্শ দেব ।

ওপেন সোর্স লাইসেন্সের পাশাপাশি বাণিজ্যিক লাইসেন্স রয়েছে।


1
আমি এটি দেখেছি কিন্তু এটি ম্যাক্রোগুলি ব্যবহার করে এবং মেটা-ডেটা কোড উত্পন্ন করতে উত্স কোডটির বিশ্লেষণ প্রয়োজন। আমি এই অতিরিক্ত পদক্ষেপ এড়াতে চাই। আমি একটি সি ++ গ্রন্থাগার বা সাধারণ ম্যাক্রোগুলি ব্যবহার করতে পছন্দ করব। যদিও ধারণা জন্য ধন্যবাদ।
নিক

10
কিউটি, বা অন্য একটি লাইব্রেরি একই ধরণের পদ্ধতির প্রয়োগ করছে আপনি
যেটি

5
সংকলন সময়ে অর্থ প্রদান করুন বা রানটাইমের সময় প্রদান করুন - আপনি যেভাবেই অর্থ প্রদান করছেন!
মার্টিন বেকেট

13

আপনি প্রতিবিম্ব দিয়ে কি করতে চেষ্টা করছেন?
আপনি সংকলন-সময় প্রতিবিম্বের সীমাবদ্ধ ফর্ম হিসাবে বুস্ট ধরণের বৈশিষ্ট্য এবং টাইপফ লাইব্রেরি ব্যবহার করতে পারেন । এটি হ'ল, আপনি কোনও টেমপ্লেটে পাস করা কোনও প্রকারের প্রাথমিক বৈশিষ্ট্যগুলি পরীক্ষা করতে ও সংশোধন করতে পারেন।


13

সম্পাদনা : সিএএমপি আর রক্ষণাবেক্ষণ করা হয় না; দুটি কাঁটাচামচ পাওয়া যায়:

  • একজনকে সিএএমপিও বলা হয় এবং এটি একই API এর উপর ভিত্তি করে।
  • পন্ডার একটি আংশিক পুনর্লিখন, এবং এটি বুস্টের প্রয়োজন হয় না বলে পছন্দ করা হবে; এটি সি ++ 11 ব্যবহার করছে।

সিএএমপি একটি এমআইটি লাইসেন্সযুক্ত লাইব্রেরি (পূর্বে এলজিপিএল) যা সি ++ ভাষার প্রতিচ্ছবি যুক্ত করে। সংকলনের জন্য এটি একটি নির্দিষ্ট প্রাকপ্রসেসিং পদক্ষেপের প্রয়োজন হয় না, তবে বাইন্ডিংটি ম্যানুয়ালি তৈরি করতে হবে।

বর্তমান Tegesoft লাইব্রেরি বুস্ট ব্যবহার করে, তবে সি ++ 11 ব্যবহার করে একটি কাঁটাচামচও রয়েছে যার জন্য আর বুস্টের প্রয়োজন হয় না


11

আপনি একবারে যা করেছেন তার মতো আমি কিছু করেছি এবং কিছু স্তরের প্রতিফলন এবং উচ্চ-স্তরের বৈশিষ্ট্যগুলিতে অ্যাক্সেস পাওয়া সম্ভব হলেও রক্ষণাবেক্ষণের মাথাব্যথা এটি উপযুক্ত নাও হতে পারে। আমার সিস্টেমটি ইউআই ক্লাসগুলি ব্যবসায়ের যুক্তি থেকে পুরোপুরি বিচ্ছিন্ন রাখতে প্রতিনিধিদলের মাধ্যমে অবজেক্টিভ-সি এর বার্তা পাস এবং ফরওয়ার্ডিংয়ের ধারণার মত ছিল। এটি করার উপায়টি হ'ল কিছু বেস ক্লাস তৈরি করা যা প্রতীকগুলি ম্যাপিংয়ে সক্ষম (আমি একটি স্ট্রিং পুল ব্যবহার করেছি তবে আপনি এ্যামস দিয়ে এটি করতে পারতেন যদি আপনি গতি পছন্দ করেন এবং মোট নমনীয়তার তুলনায় সংকলন-সময় ত্রুটি পরিচালনা করতে পারেন) পয়েন্টারগুলি কার্য করতে (আসলে না খাঁটি ফাংশন পয়েন্টার, তবে বুস্টের সাথে বুস্টের সাথে মিল রয়েছে এমন কিছু। ফাংশন - যা আমার কাছে তখন অ্যাক্সেস ছিল না)। আপনার সদস্য ভেরিয়েবলগুলির জন্য আপনি একই জিনিসটি করতে পারেন যতক্ষণ না আপনার কোনও সাধারণ বেস শ্রেণি থাকে যে কোনও মান উপস্থাপন করতে সক্ষম। পুরো সিস্টেমটি কী-ভ্যালু কোডিং এবং ডেলিগেশনের একটি অপরিবর্তিত ফেলা ছিল, কয়েকটি পার্শ্ব প্রতিক্রিয়া যা সম্ভবত সমস্ত শ্রেণীর জন্য প্রয়োজনীয় সময়সীমার জন্য মূল্যবান ছিল যা সিস্টেমটি তার সমস্ত পদ্ধতির সাথে মেলে এবং সদস্যদের আইনী কল দিয়ে মিলিত হতে পারে। : 1) যে কোনও শ্রেণি শিরোনাম অন্তর্ভুক্ত না করে বা জাল বেস ক্লাসগুলি না লিখে অন্য শ্রেণীর যে কোনও পদ্ধতিতে কল করতে পারে যাতে ইন্টারফেসটি সংকলকের জন্য পূর্বনির্ধারিত হতে পারে; এবং 2) সদস্য ভেরিয়েবলের গিটার এবং সেটটারগুলি থ্রেড-নিরাপদ করা সহজ ছিল কারণ সমস্ত মানগুলির বেস শ্রেণিতে 2 টি পদ্ধতির মাধ্যমে তাদের মানগুলি পরিবর্তন করা বা অ্যাক্সেস করা সবসময়ই করা হত। পুরো সিস্টেমটি কী-ভ্যালু কোডিং এবং ডেলিগেশনের একটি অপরিবর্তিত ফেলা ছিল, কয়েকটি পার্শ্ব প্রতিক্রিয়া যা সম্ভবত সমস্ত শ্রেণীর জন্য প্রয়োজনীয় সময়সীমার জন্য মূল্যবান ছিল যা সিস্টেমটি তার সমস্ত পদ্ধতির সাথে মেলে এবং সদস্যদের আইনী কল দিয়ে মিলিত হতে পারে। : 1) যে কোনও শ্রেণি শিরোনাম অন্তর্ভুক্ত না করে বা জাল বেস ক্লাসগুলি না লিখে অন্য শ্রেণীর যে কোনও পদ্ধতিতে কল করতে পারে যাতে ইন্টারফেসটি সংকলকের জন্য পূর্বনির্ধারিত হতে পারে; এবং 2) সদস্য ভেরিয়েবলের গিটার এবং সেটটারগুলি থ্রেড-নিরাপদ করা সহজ ছিল কারণ সমস্ত মানগুলির বেস শ্রেণিতে 2 টি পদ্ধতির মাধ্যমে তাদের মানগুলি পরিবর্তন করা বা অ্যাক্সেস করা সবসময়ই করা হত। পুরো সিস্টেমটি কী-ভ্যালু কোডিং এবং ডেলিগেশনের একটি অপরিবর্তিত ফেলা ছিল, কয়েকটি পার্শ্ব প্রতিক্রিয়া যা সম্ভবত সমস্ত শ্রেণীর জন্য প্রয়োজনীয় সময়সীমার জন্য মূল্যবান ছিল যা সিস্টেমটি তার সমস্ত পদ্ধতির সাথে মেলে এবং সদস্যদের আইনী কল দিয়ে মিলিত হতে পারে। : 1) যে কোনও শ্রেণি শিরোনাম অন্তর্ভুক্ত না করে বা জাল বেস ক্লাসগুলি না লিখে অন্য শ্রেণীর যে কোনও পদ্ধতিতে কল করতে পারে যাতে ইন্টারফেসটি সংকলকের জন্য পূর্বনির্ধারিত হতে পারে; এবং 2) সদস্য ভেরিয়েবলের গিটার এবং সেটটারগুলি থ্রেড-নিরাপদ করা সহজ ছিল কারণ সমস্ত মানগুলির বেস শ্রেণিতে 2 টি পদ্ধতির মাধ্যমে তাদের মানগুলি পরিবর্তন করা বা অ্যাক্সেস করা সবসময়ই করা হত। 1) যে কোনও শ্রেণি শিরোনাম অন্তর্ভুক্ত না করে বা জাল বেস ক্লাস না লিখে অন্য শ্রেণীর যে কোনও পদ্ধতিতে কল করতে পারে যাতে ইন্টারফেসটি সংকলকের জন্য পূর্বনির্ধারিত হতে পারে; এবং 2) সদস্য ভেরিয়েবলের গিটার এবং সেটটারগুলি থ্রেড-নিরাপদ করা সহজ ছিল কারণ সমস্ত মানগুলির বেস শ্রেণিতে 2 টি পদ্ধতির মাধ্যমে তাদের মানগুলি পরিবর্তন করা বা অ্যাক্সেস করা সবসময়ই করা হত। 1) যে কোনও শ্রেণি শিরোনাম অন্তর্ভুক্ত না করে বা জাল বেস ক্লাস না লিখে অন্য শ্রেণীর যে কোনও পদ্ধতিতে কল করতে পারে যাতে ইন্টারফেসটি সংকলকের জন্য পূর্বনির্ধারিত হতে পারে; এবং 2) সদস্য ভেরিয়েবলের গিটার এবং সেটটারগুলি থ্রেড-নিরাপদ করা সহজ ছিল কারণ সমস্ত মানগুলির বেস শ্রেণিতে 2 টি পদ্ধতির মাধ্যমে তাদের মানগুলি পরিবর্তন করা বা অ্যাক্সেস করা সবসময়ই করা হত।

এটি এমন কিছু সত্যই অদ্ভুত কাজ করার সম্ভাবনা তৈরি করেছিল যা অন্যথায় সি ++ এ সহজ নয়। উদাহরণস্বরূপ, আমি একটি অ্যারে অবজেক্ট তৈরি করতে পারি যার মধ্যে নিজেই সহ যে কোনও ধরণের ইচ্ছামত আইটেম রয়েছে এবং সমস্ত অ্যারে আইটেমগুলিতে একটি বার্তা প্রেরণ করে এবং ফেরতের মানগুলি (লিস্পে মানচিত্রের সমান) সংগ্রহ করে নতুনভাবে অ্যারে তৈরি করতে পারি। আরেকটি হ'ল মূল-মান পর্যবেক্ষণের বাস্তবায়ন, যার মাধ্যমে আমি নিয়মিত ডেটা পোলিংয়ের পরিবর্তে বা অযৌক্তিকরূপে ডিসপ্লে পুনরায় আঁকানোর পরিবর্তে ব্যাকএন্ড ক্লাসের সদস্যদের পরিবর্তনের বিষয়ে অবিলম্বে প্রতিক্রিয়া জানাতে UI সেট করতে সক্ষম হয়েছি।

আপনার কাছে আরও আকর্ষণীয় হ'ল এটি হ'ল আপনি কোনও শ্রেণীর জন্য সংজ্ঞায়িত সমস্ত পদ্ধতি এবং সদস্যদেরও ডাম্প করতে পারেন, এবং স্ট্রিং আকারে কোনও কম নয়।

সিস্টেমে ডাউনসাইড যা আপনাকে বিরক্ত করা থেকে নিরুৎসাহিত করতে পারে: সমস্ত বার্তা এবং কী-মানগুলি যুক্ত করা অত্যন্ত ক্লান্তিকর; এটি কোনও প্রতিবিম্ব ছাড়াই ধীর; আপনি হিংসাত্মক আবেগের সাথে আপনার কোডবেস দেখে boost::static_pointer_castএবং ঘৃণা করতে শুরু করবেন boost::dynamic_pointer_cast; দৃ strongly়ভাবে টাইপ করা সিস্টেমের সীমাবদ্ধতা এখনও আছে, আপনি সত্যিই কেবল তাদের কিছুটা আড়াল করছেন যাতে এটি স্পষ্ট হয় না। আপনার স্ট্রিংয়ের টাইপগুলি কোনও মজাদার বা আশ্চর্যরূপে আবিষ্কার করা সহজ নয়।

এটির মতো কীভাবে বাস্তবায়ন করা যায়: কিছু সাধারণ বেসের জন্য ভাগ করে নেওয়া এবং দুর্বল পয়েন্টারগুলি ব্যবহার করুন (খনিটি খুব কল্পনাপ্রসূতভাবে "অবজেক্ট" নামে অভিহিত হত) এবং আপনি যে সমস্ত প্রকারের ব্যবহার করতে চান তা অনুসন্ধান করুন। আমি বুস্ট.ফান্শনটি ইনস্টল করার পরামর্শ দিয়েছিলাম যেভাবে আমি এটি না করে যা ফাংশন পয়েন্টার কলগুলিকে মোড়ানোর জন্য কিছু কাস্টম ক্রেপ এবং এক টন কুরুচিপূর্ণ ম্যাক্রো সহ ছিল। যেহেতু সবকিছু ম্যাপ করা আছে, অবজেক্টগুলি পরীক্ষা করা সমস্ত কীগুলির মাধ্যমে পুনরাবৃত্তি করার বিষয়। যেহেতু আমার ক্লাসগুলি মূলত কেবল সি ++ ব্যবহার করে সম্ভব কোকোয়ার সরাসরি ফিরফের কাছাকাছি ছিল, যদি আপনি এরকম কিছু চান তবে আমি কোকো ডকুমেন্টেশনটি একটি নীলনকশা হিসাবে ব্যবহার করার পরামর্শ দিই।


আরে, @ মিশেল; আপনার কাছে এখনও এর জন্য সোর্স কোড রয়েছে, না আপনি এ থেকে মুক্তি পেয়েছেন? আপনি যদি কিছু মনে করেন না তবে আমি এটি একবার দেখে নিতে চাই।
এলোমেলো ডেডেভেল

উফফফফফ, তোমার নাম ভুল বানান! আশ্চর্যের কিছু নেই যে আমি কখনই উত্তর পাই নি ...
এলোমেলো ডিএসডিভেল

10

সেখানে সি প্রতিফলন জন্য আরেকটি নতুন গ্রন্থাগার ++ বলা হয় RTTR (রান টাইম প্রকার প্রতিফলন, তাও দেখতে GitHub )।

ইন্টারফেসটি সি # তে প্রতিবিম্বের মতো এবং এটি কোনও আরটিটিআই ছাড়াই কাজ করে।


8

আমার সি ++ দিন থেকে আমি যে দুটি প্রতিবিম্বের মতো সমাধানগুলি জানি তা হ'ল:

1) আরটিটিআই ব্যবহার করুন, যা আপনার প্রতিবিম্বের মতো আচরণ তৈরি করতে আপনাকে একটি বুটস্ট্র্যাপ সরবরাহ করবে, যদি আপনি 'অবজেক্ট' বেস শ্রেণি থেকে আপনার সমস্ত শ্রেণি পেতে সক্ষম হন। এই শ্রেণিটি getMethod, getBaseClass ইত্যাদির মতো কিছু পদ্ধতি সরবরাহ করতে পারে those সেই পদ্ধতিগুলি কীভাবে কাজ করে তা আপনাকে নিজের ধরণের সাজসজ্জার জন্য ম্যানুয়ালি কিছু ম্যাক্রোগুলি যুক্ত করতে হবে, যা পর্দার আড়ালে গেটমেথডস ইত্যাদির উত্তর সরবরাহ করতে টাইপটিতে মেটাডেটা তৈরি করে etc.

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

এই দুটি সমাধানই কিছুটা কুৎসিত হলেও! আপনাকে সি # এর বিলাসিতা প্রশংসা করার জন্য কিছুটা সি ++ এর মতো কিছুই নেই।

শুভকামনা


এটি আপনার প্রস্তাবিত ডিআইএ এসডিকে জিনিসটির সাথে কৌতূহল এবং একটি বিশাল হ্যাক।
স্কাইকি

7

সম্পাদনা: broken ই ফেব্রুয়ারী, ২০১ broken সালের হিসাবে ভাঙা লিঙ্কটি আপডেট হয়েছে Updated

আমি মনে করি নুন এটির উল্লেখ করেছেন:

সিইআরএন এ তারা সি ++ এর জন্য একটি সম্পূর্ণ প্রতিবিম্ব সিস্টেম ব্যবহার করে:

সিআরএন রিফ্লেক্স । মনে হচ্ছে এটি খুব ভাল কাজ করছে।


@ j4nbur53 লিঙ্কটি নষ্ট হয়ে গেছে বলে মনে হচ্ছে তারা মাইলফলকে পৌঁছেছে: root.cern.ch
জার্মান ডায়াগো

এটা কি হতে পারে যে আপনি এই লিঙ্কটি মানে root.cern.ch/root/doc/ROOTUsersGuideHTML/ch07.html অধ্যায় প্রতিবিম্ব?
মোস্তোস্কি

এই root.cern.ch/how/how-use-reflex চেষ্টা করুন । রিফ্লেক্স এমন একটি জেনারেটর হিসাবে কাজ করে যা আপনার শিরোনামের ফাইলগুলিকে পার্স করে এবং সি ++ ইনট্রোস্পেকশন কোড / লাইব্রেরি উত্পন্ন করে, যেটির সাথে আপনি লিঙ্ক করতে পারেন এবং একটি সাধারণ এপিআই ব্যবহার করতে পারেন।
অ্যাডাম রাইজকোভস্কি

6

এই প্রশ্নটি এখন কিছুটা পুরানো (জানেন না কেন আমি আজও পুরানো প্রশ্নগুলিতে আঘাত করি) তবে আমি BOOST_FUSION_ADAPT_ભરের সম্পর্কে ভাবছিলাম যা সংকলন-সময়ের প্রতিচ্ছবি প্রবর্তন করে।

এটি অবশ্যই রান-টাইম প্রতিবিম্বের জন্য মানচিত্র করা আপনার উপর নির্ভর করবে এবং এটি খুব সহজ হবে না তবে এই দিক থেকে এটি সম্ভব, যদিও এটি বিপরীতে থাকবে না :)

আমি সত্যিই মনে করি যে এটির সাথে ম্যাপ্রো স্থাপনের একটি ম্যাক্রো BOOST_FUSION_ADAPT_STRUCTরানটাইম আচরণ পাওয়ার জন্য প্রয়োজনীয় পদ্ধতি তৈরি করতে পারে।


2
মিঙ্গুয়া দ্বারা (যিনি মূলত পোস্টটি সম্পাদনা করেছেন): আমি এই BOOST_FUSION_ADAPT_ભરের সমাধানটি খনন করেছি এবং শেষ পর্যন্ত একটি উদাহরণ নিয়ে এসেছি। এই আরও নতুন প্রশ্নটি দেখুন - বুস্ট ফিউশন অ্যাডাপ্ট_স্ট্রিক্ট সহ নেস্টার্ড স্ট্রাক্ট ফিল্ডে সি ++ পুনরাবৃত্তি
ম্যাথিউ এম।

দুর্দান্ত, ম্যাথিউ! গত বছরের পুরো সময়ে আপনার ইঙ্গিতগুলি এখানে এবং সেখানে দেখেছি কেবল উপলব্ধি হয়ে গেছে। তারা এখনও অবধি সম্পর্কিত খেয়াল করেনি। তারা খুব অনুপ্রেরণা ছিল।
মিঙ্গুয়া

6

আমি মনে করি আপনি ডমিনিক ফিলিয়ন দ্বারা "সি ++ তে প্রতিচ্ছবি ব্যবহারের জন্য টেমপ্লেট ব্যবহার করে" নিবন্ধটি আকর্ষণীয় পেতে পারেন। এটি গেম প্রোগ্রামিং রত্ন 5 এর 1.4 বিভাগে রয়েছে । দুর্ভাগ্যক্রমে আমার সাথে আমার অনুলিপিটি নেই, তবে এটির জন্য দেখুন কারণ আমি মনে করি এটি আপনাকে যা চাইছে তা ব্যাখ্যা করে।


4

এই প্রশ্নের উত্তরে পন্ডার একটি সি ++ প্রতিবিম্ব গ্রন্থাগার। আমি বিকল্পগুলি বিবেচনা করেছি এবং আমার নিজের তৈরি করার সিদ্ধান্ত নিয়েছি যেহেতু আমার সমস্ত বাক্স টিকানো এমন একটি খুঁজে পেল না।

যদিও এই প্রশ্নের দুর্দান্ত উত্তর রয়েছে, আমি টন ম্যাক্রো ব্যবহার করতে বা বুস্টের উপর নির্ভর করতে চাই না। বুস্ট একটি দুর্দান্ত গ্রন্থাগার, তবে অনেকগুলি ছোট ছোট bespoke সি ++ 0x প্রকল্প রয়েছে যা সহজ এবং দ্রুত সংকলনের সময় রয়েছে। বহিরাগতভাবে কোনও শ্রেণি সাজাতে সক্ষম হওয়ার সুবিধা রয়েছে, যেমন একটি সি ++ লাইব্রেরি মোড়ানোর মতো যা (এখনও?) সি ++ 11 সমর্থন করে না। এটি সিএএমপির কাঁটাচামচ, সি ++ 11 ব্যবহার করে, আর বুস্টের প্রয়োজন হয় না


4

প্রতিফলনটি মূলত যা রানটাইম কোডটি জিজ্ঞাসা করতে পারে কোডটিতে পায়ের ছাপ হিসাবে ছেড়ে যাওয়ার সিদ্ধান্ত নিয়েছে। সি ++ আপনি যা ব্যবহার করেন না তার জন্য অর্থ প্রদান না করার জন্য বিখ্যাত; কারণ বেশিরভাগ লোকেরা প্রতিবিম্ব ব্যবহার করে না / চায় না, সি ++ সংকলক কিছুই রেকর্ড না করে ব্যয়টি এড়িয়ে যায় ।

সুতরাং, সি ++ প্রতিবিম্ব সরবরাহ করে না এবং এটি অন্যান্য নিয়ম যেমন উল্লেখ করেছে তেমন নিজেকে সাধারণ নিয়ম হিসাবে "অনুকরণ" করা সহজ নয়।

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

আমাদের ডিএমএস সফ্টওয়্যার পুনর্নির্ধারণের সরঞ্জামদণ্ডটি স্পষ্টত ল্যাঙ্গেজ সংজ্ঞা দ্বারা পরামিতি সংকলক প্রযুক্তি সাধারণকরণ করা হয়। এটিতে সি, সি ++, জাভা, সিওবিএল, পিএইচপি, ... এর ল্যাঙ্গেজ সংজ্ঞা রয়েছে ...

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


3

আপনি এখানে অন্য লাইব্রেরিটি খুঁজে পেতে পারেন: http://www.garret.ru/cppreflection/docs/reflect.html এটি 2 টি উপায় সমর্থন করে: ডিবাগ তথ্য থেকে টাইপ তথ্য প্রাপ্তি এবং প্রোগ্রামারকে এই তথ্য সরবরাহ করতে দিন।

আমি আমার প্রকল্পের প্রতিচ্ছবিতে আগ্রহী এবং এই লাইব্রেরিটি পেয়েছি, আমি এটি এখনও চেষ্টা করি নি, তবে এই লোকটির কাছ থেকে অন্যান্য সরঞ্জাম চেষ্টা করেছি এবং তারা কীভাবে কাজ করে তা আমি পছন্দ করি :-)


3

ক্লাসডেস্ক http://classdesc.sf.net দেখুন । এটি শ্রেণি "বর্ণনাকারী" আকারে প্রতিবিম্ব সরবরাহ করে, যে কোনও স্ট্যান্ডার্ড সি ++ কম্পাইলারের সাথে কাজ করে (হ্যাঁ এটি ভিজ্যুয়াল স্টুডিও পাশাপাশি জিসিসির সাথে কাজ করার জন্য পরিচিত) এবং উত্স কোড টীকাটির প্রয়োজন হয় না (যদিও কিছু ছদ্মবেশী পরিস্থিতি পরিচালনা করতে প্রগমাস বিদ্যমান রয়েছে) )। এটি এক দশকেরও বেশি সময় ধরে বিকাশে রয়েছে এবং এটি বেশ কয়েকটি শিল্প স্কেল প্রকল্পে ব্যবহৃত হয়।


1
স্ট্যাক ওভারফ্লোতে আপনাকে স্বাগতম। যদিও এই উত্তরটি বিষয়টিতে রয়েছে, এটি উল্লেখ করা গুরুত্বপূর্ণ যে আপনি এই সফ্টওয়্যারটির লেখক, এটি পরিষ্কার করার জন্য এটি নিরপেক্ষ সুপারিশ নয় :-)
ম্যাথিউ স্ট্রব্রিজ idge

2

আমি যখন সি ++ তে প্রতিবিম্ব চেয়েছিলাম তখন আমি এই নিবন্ধটি পড়ি এবং সেখানে যা দেখেছি তার উন্নতি হয়েছিল। দুঃখিত, কোন পারে না। আমি ফলাফলটির মালিক নই ... তবে আপনি অবশ্যই আমার যা পেয়েছিলেন তা সেখান থেকে পেতে পারেন।

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


2

দেখে মনে হচ্ছে সি ++ তে এখনও এই বৈশিষ্ট্যটি নেই। এবং সি ++ 11 স্থগিত প্রতিবিম্বও ((

কিছু ম্যাক্রো অনুসন্ধান করুন বা নিজের তৈরি করুন। কিউটি প্রতিবিম্বের সাথেও সহায়তা করতে পারে (যদি এটি ব্যবহার করা যায়)।


2

সি -++ তে বাইরের বাইরে প্রতিবিম্ব সমর্থিত না হলেও এটি প্রয়োগ করা খুব বেশি কঠিন নয় hard আমি এই দুর্দান্ত নিবন্ধটির মুখোমুখি হয়েছি: http://replicaisland.blogspot.co.il/2010/11/building-reflective-object-system-in-c.html

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

নীচের লাইন - প্রতিফলন সঠিকভাবে করা হলে পরিশোধ করতে পারে, এবং এটি সি ++ এ সম্পূর্ণ সম্ভাব্য।


2

আমি স্বয়ংক্রিয় অন্তঃসংশোধন / প্রতিবিম্ব টুলকিট "আইডিকে" এর অস্তিত্বের বিজ্ঞাপন দিতে চাই। এটি Qt এর মতো একটি মেটা-সংকলক ব্যবহার করে এবং সরাসরি অবজেক্ট ফাইলে মেটা তথ্য যুক্ত করে। এটি ব্যবহার করা সহজ বলে দাবি করা হচ্ছে। বাহ্যিক নির্ভরতা নেই। এমনকি এটি আপনাকে স্বয়ংক্রিয়ভাবে std :: স্ট্রিং প্রতিফলিত করতে এবং তারপরে স্ক্রিপ্টগুলিতে এটি ব্যবহার করার অনুমতি দেয়। দয়া করে তাকান idk


2

আপনি যদি অপেক্ষাকৃত সহজ সি ++ প্রতিবিম্বের সন্ধান করছেন - আমি বিভিন্ন উত্স থেকে ম্যাক্রো / সংজ্ঞায়িত করেছি এবং সেগুলি কীভাবে কাজ করে তা মন্তব্য করেছি mented আপনি এখান থেকে শিরোনাম ফাইল ডাউনলোড করতে পারেন:

https://github.com/tapika/TestCppReflect/blob/master/MacroHelpers.h

সংজ্ঞায়িত সেট, এর উপরে কার্যকারিতা:

https://github.com/tapika/TestCppReflect/blob/master/CppReflect.h https://github.com/tapika/TestCppReflect/blob/master/CppReflect.cpp https://github.com/tapika/TestCppReflect/ ফোঁটা / মাস্টার / TypeTraits.h

নমুনা অ্যাপ্লিকেশনটি এখানে গিট সংগ্রহস্থলীতেও রয়েছে: https://github.com/tapika/TestCppReflect/

আমি এখানে আংশিক ব্যাখ্যা সহ কপি করব:

#include "CppReflect.h"
using namespace std;


class Person
{
public:

    // Repack your code into REFLECTABLE macro, in (<C++ Type>) <Field name>
    // form , like this:

    REFLECTABLE( Person,
        (CString)   name,
        (int)       age,
...
    )
};

void main(void)
{
    Person p;
    p.name = L"Roger";
    p.age = 37;
...

    // And here you can convert your class contents into xml form:

    CStringW xml = ToXML( &p );
    CStringW errors;

    People ppl2;

    // And here you convert from xml back to class:

    FromXml( &ppl2, xml, errors );
    CStringA xml2 = ToXML( &ppl2 );
    printf( xml2 );

}

REFLECTABLEনির্দিষ্ট শ্রেণীর নাম + ক্ষেত্রের নামটি সংজ্ঞায়িত করে offsetof- নির্দিষ্ট ক্ষেত্রের মেমরিটি কোন স্থানে রয়েছে তা সনাক্ত করতে। আমি যথাসম্ভব নেট নেট পরিভাষা বাছাই করার চেষ্টা করেছি, তবে সি ++ এবং সি # আলাদা, তাই এটি 1 থেকে 1 নয় not পুরো সি ++ প্রতিবিম্ব মডেলটি ক্লাসে থাকে TypeInfoএবং FieldInfoক্লাসে থাকে।

ডেমো কোডটি এক্সএমএলে আনতে এবং এক্সএমএল থেকে এটি পুনরুদ্ধার করতে আমি পগি এক্সএমএল পার্সার ব্যবহার করেছি।

সুতরাং ডেমো কোড দ্বারা উত্পাদিত আউটপুট এর মতো দেখাচ্ছে:

<?xml version="1.0" encoding="utf-8"?>
<People groupName="Group1">
    <people>
        <Person name="Roger" age="37" />
        <Person name="Alice" age="27" />
        <Person name="Cindy" age="17" />
    </people>
</People>

টাইপট্রেট ক্লাসের মাধ্যমে যে কোনও 3-ডি পার্টি পার্টি শ্রেণি / কাঠামো সমর্থন সক্ষম করা এবং আংশিক টেম্পলেট স্পেসিফিকেশন - আপনার নিজস্ব টাইপট্রেটস টি শ্রেণির সংজ্ঞা দিতে, একইভাবে সিএসট্রিং বা ইনট - উদাহরণ কোড দেখুন

https://github.com/tapika/TestCppReflect/blob/master/TypeTraits.h#L195

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

এই সমাধানটি একাধিক সাবক্লাস সহ এক শ্রেণির এক শট সিরিয়ালাইজেশনের জন্য প্রযোজ্য।

আপনি যদি ক্লাস পার্টস ক্রমিকায়নের জন্য বা এমনকি কার্যকারিতা প্রতিচ্ছবি কলগুলি কী উত্পাদন করে তা নিয়ন্ত্রণ করার জন্য মেকানিজম সন্ধান করছেন, আপনি নিম্নলিখিত সমাধানটি একবার দেখে নিতে পারেন:

https://github.com/tapika/cppscriptcore/tree/master/SolutionProjectModel

ইউটিউব ভিডিও থেকে আরও বিস্তারিত তথ্য পাওয়া যাবে:

সি ++ রানটাইমের ধরণের প্রতিবিম্ব https://youtu.be/TN8tJijkeFE

সি ++ প্রতিবিম্ব কীভাবে কাজ করবে সে সম্পর্কে আমি আরও গভীরভাবে ব্যাখ্যা করার চেষ্টা করছি।

নমুনা কোড উদাহরণস্বরূপ এর মতো দেখাবে:

https://github.com/tapika/cppscriptcore/blob/master/SolutionProjectModel/testCppApp.cpp

c.General.IntDir = LR"(obj\$(ProjectName)_$(Configuration)_$(Platform)\)";
c.General.OutDir = LR"(bin\$(Configuration)_$(Platform)\)";
c.General.UseDebugLibraries = true;
c.General.LinkIncremental = true;
c.CCpp.Optimization = optimization_Disabled;
c.Linker.System.SubSystem = subsystem_Console;
c.Linker.Debugging.GenerateDebugInformation = debuginfo_true;

তবে এখানে প্রতিটি পদক্ষেপে কার্যত সি ++ এর বৈশিষ্ট্যগুলি ব্যবহার করে ফাংশন কলে ফলাফল দেয় __declspec(property(get =, put ... )

যা পথের আকারে সি ++ ডেটা টাইপস, সি ++ সম্পত্তির নাম এবং শ্রেণীর উদাহরণ পয়েন্টারগুলির উপর সম্পূর্ণ তথ্য পায় এবং সেই তথ্যের উপর ভিত্তি করে আপনি এক্সএমএল, জেসন তৈরি করতে পারেন বা এমনকি ইন্টারনেটের মাধ্যমে এটি সিরিয়ালাইজ করতে পারেন।

এই জাতীয় ভার্চুয়াল কলব্যাক ফাংশনগুলির উদাহরণগুলি এখানে পাওয়া যাবে:

https://github.com/tapika/cppscriptcore/blob/master/SolutionProjectModel/VCConfiguration.cpp

ফাংশন ReflectCopyএবং ভার্চুয়াল ফাংশন দেখুন ::OnAfterSetProperty

তবে বিষয়টি যেহেতু সত্যই অগ্রসর - তাই আমি প্রথমে ভিডিওর মাধ্যমে পরীক্ষা করার পরামর্শ দিই।

আপনার যদি কিছু উন্নতি ধারণা থাকে তবে নির্দ্বিধায় আমার সাথে যোগাযোগ করুন।


1

সি ++ তে প্রতিফলন খুব দরকারী, সেখানে ক্ষেত্রে প্রতিটি সদস্যের জন্য আপনাকে কিছু পদ্ধতি চালনা করতে হবে (উদাহরণস্বরূপ: সিরিয়ালাইজেশন, হ্যাশিং, তুলনা)। আমি জেনেরিক সমাধান নিয়ে এসেছি, খুব সাধারণ বাক্য গঠন সহ:

struct S1
{
    ENUMERATE_MEMBERS(str,i);
    std::string str;
    int i;
};
struct S2
{
    ENUMERATE_MEMBERS(s1,i2);
    S1 s1;
    int i2;
};

যেখানে ENUMERATE_MEMBERS হ'ল একটি ম্যাক্রো, যা পরে বর্ণিত হয়েছে (আপডেট):

ধরুন আমরা int এবং std :: স্ট্রিংয়ের জন্য সিরিয়ালাইজেশন ফাংশনটি সংজ্ঞায়িত করেছি:

void EnumerateWith(BinaryWriter & writer, int val)
{
    //store integer
    writer.WriteBuffer(&val, sizeof(int));
}
void EnumerateWith(BinaryWriter & writer, std::string val)
{
    //store string
    writer.WriteBuffer(val.c_str(), val.size());
}

এবং আমাদের "সিক্রেট ম্যাক্রো" এর কাছে জেনেরিক ফাংশন রয়েছে;)

template<typename TWriter, typename T>
auto EnumerateWith(TWriter && writer, T && val) -> is_enumerable_t<T>
{
    val.EnumerateWith(write); //method generated by ENUMERATE_MEMBERS macro
}

এখন আপনি লিখতে পারেন

S1 s1;
S2 s2;
//....
BinaryWriter writer("serialized.bin");

EnumerateWith(writer, s1); //this will call EnumerateWith for all members of S1
EnumerateWith(writer, s2); //this will call EnumerateWith for all members of S2 and S2::s1 (recursively)

সুতরাং কাঠামো সংজ্ঞায় ENUMERATE_MEMBERS ম্যাক্রো থাকা, আপনি মূল ধরণটি স্পর্শ না করেই সিরিয়ালাইজেশন, তুলনা, হ্যাশিং এবং অন্যান্য স্টাফ তৈরি করতে পারেন, কেবলমাত্র প্রতিটি প্রকারের জন্য "এনুমারেট উইথ" পদ্ধতিটি প্রয়োগ করা প্রয়োজন, যা গণনা অনুযায়ী প্রতি বিণনযোগ্য নয় (বাইনারি রাইটারের মতো) । সাধারণত আপনার প্রকল্পে যে কোনও ধরণের সমর্থন করতে আপনাকে 10-20 "সাধারণ" প্রকারগুলি প্রয়োগ করতে হবে।

এই ম্যাক্রোর রান-টাইমে স্ট্রাকচার তৈরি / ধ্বংসের শূন্য-ওভারহেড থাকা উচিত এবং টি-এনামারেট উইথ () এর কোডটি অন-ডিমান্ড তৈরি করা উচিত, যা এটি টেমপ্লেট-ইনলাইন ফাংশন তৈরি করে অর্জন করা যেতে পারে, সুতরাং একমাত্র ওভারহেড সমস্ত কাহিনীটি প্রতিটি স্ট্রাক্টে ENUMERATE_MEMBERS (এম 1, এম 2, এম 3 ...) যুক্ত করা হয়, তবে প্রতিটি ধরণের সদস্য অনুসারে নির্দিষ্ট পদ্ধতি প্রয়োগ করা যে কোনও সমাধানের ক্ষেত্রে আবশ্যক, সুতরাং আমি এটিকে ওভারহেড হিসাবে ধরে নিই না।

আপডেট: ENUMERATE_MEMBERS ম্যাক্রোর খুব সাধারণ প্রয়োগ হচ্ছে (তবে এটি সংখ্যার কাঠামোগুলি থেকে উত্তরাধিকারের জন্য কিছুটা বাড়ানো যেতে পারে)

#define ENUMERATE_MEMBERS(...) \
template<typename TEnumerator> inline void EnumerateWith(TEnumerator & enumerator) const { EnumerateWithHelper(enumerator, __VA_ARGS__ ); }\
template<typename TEnumerator> inline void EnumerateWith(TEnumerator & enumerator) { EnumerateWithHelper(enumerator, __VA_ARGS__); }

// EnumerateWithHelper
template<typename TEnumerator, typename ...T> inline void EnumerateWithHelper(TEnumerator & enumerator, T &...v) 
{ 
    int x[] = { (EnumerateWith(enumerator, v), 1)... }; 
}

// Generic EnumerateWith
template<typename TEnumerator, typename T>
auto EnumerateWith(TEnumerator & enumerator, T & val) -> std::void_t<decltype(val.EnumerateWith(enumerator))>
{
    val.EnumerateWith(enumerator);
}

এবং এই 15 লাইনের কোডের জন্য আপনার কোনও তৃতীয় পক্ষের গ্রন্থাগার প্রয়োজন নেই;)


1

আপনি বুস্ট :: হানা লাইব্রেরি থেকে BOOST_HANA_DEFINE_ نقشيCT এর সাথে স্ট্রকের জন্য দুর্দান্ত স্ট্যাটিক প্রতিবিম্ব বৈশিষ্ট্যগুলি অর্জন করতে পারেন ।
হানা কেবল বহুমুখী, কেবল আপনার মনে থাকা ব্যবহারের জন্য নয় তবে প্রচুর টেম্পলেট বিপণনের জন্য।


1

রেণ্ডম এক্সেস প্রতিফলন সব ক্ষেত্র / টাইপ তথ্যে পারেন অ্যারে পাওয়া হতে পারে অথবা অ্যারে এক্সেস মত মনে করার জন্য ডিজাইন করা হয় - গ্রন্থাগার মোটামুটি সহজ এবং স্বজ্ঞাত প্রতিফলন করে তোলে। এটি সি ++ 17 এর জন্য লেখা এবং ভিজ্যুয়াল স্টুডিও, জি ++, এবং কলংয়ের সাথে কাজ করে। লাইব্রেরিটি কেবলমাত্র শিরোনাম, এর অর্থ এটি ব্যবহার করতে আপনার প্রকল্পে কেবল "প্রতিচ্ছবি।" অনুলিপি করতে হবে।

প্রতিবিম্বিত স্ট্রাক্ট বা ক্লাসগুলির জন্য প্রতিচ্ছবি ম্যাক্রো প্রয়োজন, যেখানে আপনি যে শ্রেণীর প্রতিফলন করছেন তার নাম এবং ক্ষেত্রের নাম সরবরাহ করে।

class FuelTank {
    public:
        float capacity;
        float currentLevel;
        float tickMarks[2];

    REFLECT(() FuelTank, () capacity, () currentLevel, () tickMarks)
};

এটাই আছে, প্রতিচ্ছবি সেটআপ করার জন্য কোনও অতিরিক্ত কোডের প্রয়োজন নেই। বৈকল্পিকভাবে আপনি সুপারক্লাসগুলি অতিক্রম করতে সক্ষম হতে বা ক্ষেত্রের জন্য অতিরিক্ত সংকলন-সময় তথ্য যুক্ত করতে (যেমন জসন: : এড়িয়ে যান)।

ক্ষেত্রগুলির মধ্য দিয়ে লুপিং যতটা সহজ হতে পারে ...

for ( size_t i=0; i<FuelTank::Class::TotalFields; i++ )
    std::cout << FuelTank::Class::Fields[i].name << std::endl;

ক্ষেত্রের মানগুলি (যা আপনি পড়তে বা সংশোধন করতে পারেন) এবং ক্ষেত্রের ধরণের তথ্য অ্যাক্সেসের জন্য আপনি কোনও অবজেক্টের উদাহরণ দিয়ে লুপ করতে পারেন ...

FuelTank::Class::ForEachField(fuelTank, [&](auto & field, auto & value) {
    using Type = typename std::remove_reference<decltype(value)>::type;
    std::cout << TypeToStr<Type>() << " " << field.name << ": " << value << std::endl;
});

একটি জেএসএন লাইব্রেরি র‌্যান্ডমএ্যাক্সেসরিফ্লেশনের শীর্ষে নির্মিত হয়েছে যা পড়তে বা লেখার জন্য উপযুক্ত জেএসওএন আউটপুট উপস্থাপনাটিকে স্বতঃ চিহ্নিত করে এবং যেকোন প্রতিফলিত ক্ষেত্র পাশাপাশি অ্যারে এবং এসটিএল ধারকগুলিকে পুনরাবৃত্তি করতে পারে।

struct MyOtherObject { int myOtherInt; REFLECT(() MyOtherObject, () myOtherInt) };
struct MyObject
{
    int myInt;
    std::string myString;
    MyOtherObject myOtherObject;
    std::vector<int> myIntCollection;

    REFLECT(() MyObject, () myInt, () myString, (Reflected) myOtherObject, () myIntCollection)
};

int main()
{
    MyObject myObject = {};
    std::cout << "Enter MyObject:" << std::endl;
    std::cin >> Json::in(myObject);
    std::cout << std::endl << std::endl << "You entered:" << std::endl;
    std::cout << Json::pretty(myObject);
}

উপরেরটি এমনভাবে চালানো যেতে পারে ...

Enter MyObject:
{
  "myInt": 1337, "myString": "stringy", "myIntCollection": [2,4,6],
  "myOtherObject": {
    "myOtherInt": 9001
  }
}


You entered:
{
  "myInt": 1337,
  "myString": "stringy",
  "myOtherObject": {
    "myOtherInt": 9001
  },
  "myIntCollection": [ 2, 4, 6 ]
}

আরো দেখুন...


0

আপনি যদি কোনও ফাংশনটিতে এটির জন্য কোনও পয়েন্টার ঘোষণা করেন:

int (*func)(int a, int b);

আপনি এই ফাংশনটির জন্য মেমরিতে একটি স্থান নির্ধারণ করতে পারেন (প্রয়োজন libdlএবং dlopen)

#include <dlfcn.h>

int main(void)
{
    void *handle;
    char *func_name = "bla_bla_bla";
    handle = dlopen("foo.so", RTLD_LAZY);
    *(void **)(&func) = dlsym(handle, func_name);
    return func(1,2);
}

ইন্ডায়ারেশন ব্যবহার করে স্থানীয় প্রতীকটি লোড করতে, আপনি dlopenকলিং বাইনারি ( argv[0]) এ ব্যবহার করতে পারেন ।

এই কেবল প্রয়োজন (ব্যতীত অন্য dlopen(), libdlএবং dlfcn.hআর্গুমেন্ট এবং ফাংশন ধরণ বুদ্ধিমান হয়)।

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