না, memcmp
এটি করা উপযুক্ত নয়। এবং সি ++ এর প্রতিবিম্ব এই মুহূর্তে এটি করার জন্য অপর্যাপ্ত (পরীক্ষামূলক সংকলকগুলি হতে পারে যা ইতিমধ্যে এটি করার জন্য যথেষ্ট প্রতিফলনকে সমর্থন করে এবং সি ++ ২৩ এর মধ্যে আপনার প্রয়োজনীয় বৈশিষ্ট্য থাকতে পারে)।
অন্তর্নির্মিত প্রতিবিম্ব ছাড়াই আপনার সমস্যা সমাধানের সহজতম উপায় হ'ল কিছু ম্যানুয়াল প্রতিবিম্ব।
এটা নাও:
struct some_struct {
int x;
double d1, d2;
char c;
};
আমরা সর্বনিম্ন কাজ করতে চাই যাতে আমরা এর মধ্যে দুটি তুলনা করতে পারি।
যদি আমাদের থাকে:
auto as_tie(some_struct const& s){
return std::tie( s.x, s.d1, s.d2, s.c );
}
অথবা
auto as_tie(some_struct const& s)
-> decltype(std::tie( s.x, s.d1, s.d2, s.c ))
{
return std::tie( s.x, s.d1, s.d2, s.c );
}
জন্য C ++ 11 , তারপর:
template<class S>
bool are_equal( S const& lhs, S const& rhs ) {
return as_tie(lhs) == as_tie(rhs);
}
একটি সুন্দর শালীন কাজ করে।
আমরা এই প্রক্রিয়াটি কিছুটা কাজের সাথে পুনরাবৃত্ত হতে প্রসারিত করতে পারি; সম্পর্কের তুলনা করার পরিবর্তে, কোনও টেমপ্লেটে মুড়ে থাকা প্রতিটি উপাদানকে তুলনা করুন এবং সেই টেম্পলেটটির operator==
পুনরাবৃত্তভাবে এই নিয়মটি প্রয়োগ করা হয় (উপাদানটির as_tie
সাথে তুলনা করতে মোড়ানো ) যদি না উপাদানটিতে ইতিমধ্যে কোনও কাজ থাকে ==
এবং অ্যারে পরিচালনা করে না।
এর জন্য প্রতি সদস্যের "প্রতিচ্ছবি" ডেটা লেখার সাথে সাথে কিছুটা লাইব্রেরি (কোডের 100ish লাইন?) প্রয়োজন হবে। আপনার কাছে থাকা স্ট্রকের সংখ্যা যদি সীমাবদ্ধ থাকে তবে প্রতি স্ট্রাক্ট কোডটি ম্যানুয়ালি লেখা সহজ হতে পারে।
পাবার উপায় সম্ভবত আছে
REFLECT( some_struct, x, d1, d2, c )
as_tie
ভয়ঙ্কর ম্যাক্রো ব্যবহার করে কাঠামো তৈরি করতে । তবে as_tie
যথেষ্ট সহজ। ইন সি ++ 11 পুনরাবৃত্তি বিরক্তিকর; এটি দরকারী:
#define RETURNS(...) \
noexcept(noexcept(__VA_ARGS__)) \
-> decltype(__VA_ARGS__) \
{ return __VA_ARGS__; }
এই পরিস্থিতিতে এবং অনেক অন্যান্য। সহ RETURNS
, লেখাটি as_tie
হ'ল:
auto as_tie(some_struct const& s)
RETURNS( std::tie( s.x, s.d1, s.d2, s.c ) )
পুনরাবৃত্তি অপসারণ।
এটি পুনরাবৃত্তি করার জন্য এখানে ছুরিকাঘাত:
template<class T,
typename std::enable_if< !std::is_class<T>{}, bool>::type = true
>
auto refl_tie( T const& t )
RETURNS(std::tie(t))
template<class...Ts,
typename std::enable_if< (sizeof...(Ts) > 1), bool>::type = true
>
auto refl_tie( Ts const&... ts )
RETURNS(std::make_tuple(refl_tie(ts)...))
template<class T, std::size_t N>
auto refl_tie( T const(&t)[N] ) {
// lots of work in C++11 to support this case, todo.
// in C++17 I could just make a tie of each of the N elements of the array?
// in C++11 I might write a custom struct that supports an array
// reference/pointer of fixed size and implements =, ==, !=, <, etc.
}
struct foo {
int x;
};
struct bar {
foo f1, f2;
};
auto refl_tie( foo const& s )
RETURNS( refl_tie( s.x ) )
auto refl_tie( bar const& s )
RETURNS( refl_tie( s.f1, s.f2 ) )
সি ++ ১ ref রেফেল_টি (অ্যারে) (সম্পূর্ণ পুনরাবৃত্তি, এমনকি অ্যারে অফ-অ্যারে সমর্থন করে):
template<class T, std::size_t N, std::size_t...Is>
auto array_refl( T const(&t)[N], std::index_sequence<Is...> )
RETURNS( std::array<decltype( refl_tie(t[0]) ), N>{ refl_tie( t[Is] )... } )
template<class T, std::size_t N>
auto refl_tie( T(&t)[N] )
RETURNS( array_refl( t, std::make_index_sequence<N>{} ) )
সরাসরি উদাহরণ ।
এখানে আমি একটি ব্যবহার std::array
এর refl_tie
। এটি সংকলনের সময়ে আমার পূর্ববর্তী রেফিলার তুলনায় অনেক দ্রুত।
এছাড়াও
template<class T,
typename std::enable_if< !std::is_class<T>{}, bool>::type = true
>
auto refl_tie( T const& t )
RETURNS(std::cref(t))
ব্যবহার std::cref
পরিবর্তে এখানে std::tie
কম্পাইল-টাইম ওভারহেড উপর বাঁচাতে পারে, যেমন cref
তুলনায় অনেক সহজ ক্লাস হয় tuple
।
অবশেষে, আপনি যোগ করা উচিত
template<class T, std::size_t N, class...Ts>
auto refl_tie( T(&t)[N], Ts&&... ) = delete;
যা অ্যারে সদস্যদের পয়েন্টারগুলিতে ক্ষয় হওয়া এবং পয়েন্টার-সমতা (যা আপনি সম্ভবত অ্যারে থেকে চান না) পিছনে পিছনে পড়তে বাধা দেবে।
এটি ব্যতীত, আপনি যদি কোনও অ-প্রতিবিম্বিত কাঠামোতে অ্যারে পাস করেন তবে এটি পয়েন্টার-থেকে-অপ-প্রতিবিম্বিত কাঠামোর উপরে refl_tie
ফিরে আসে, যা কাজ করে এবং বাজে কথা দেয়।
এটির সাহায্যে আপনি একটি সংকলন-সময় ত্রুটি শেষ করেন।
লাইব্রেরি ধরণের মাধ্যমে পুনরাবৃত্তি জন্য সমর্থন জটিল। আপনি std::tie
তাদের করতে পারেন :
template<class T, class A>
auto refl_tie( std::vector<T, A> const& v )
RETURNS( std::tie(v) )
তবে এটি এর মাধ্যমে পুনরাবৃত্তি সমর্থন করে না।