আকর্ষণীয় প্রশ্ন। আমি সম্প্রতি ধারণাগুলির বিষয়ে অ্যান্ড্রু সুতনের আলাপ দেখেছি, এবং প্রশ্নোত্তর পর্বে কেউ নিম্নলিখিত প্রশ্নটি জিজ্ঞাসা করেছেন (নিম্নলিখিত লিঙ্কে টাইমস্ট্যাম্প):
সিপিপিসন 2018: অ্যান্ড্রু সাটন "60 এর মধ্যে ধারণাগুলি: আপনার যা কিছু জানা দরকার এবং যা কিছুই আপনি করেন না"
সুতরাং প্রশ্নটি ফুটে উঠেছে: If I have a concept that says A && B && C, another says C && B && A, would those be equivalent?
অ্যান্ড্রু হ্যাঁ উত্তর দিয়েছিল, তবে সত্যটি নির্দেশ করে যে কম্পাইলারটির কিছু অভ্যন্তরীণ পদ্ধতি রয়েছে (এটি ব্যবহারকারীর কাছে স্বচ্ছ) ধারণাটিকে অণু লজিকাল প্রস্তাবগুলিতে বিভক্ত করার জন্য ( atomic constraints
অ্যান্ড্রু শব্দের সাথে শব্দটি শব্দের সাথে সংশ্লেষ করেছিলেন) এবং সেগুলি পরীক্ষা করে কিনা সমতুল্য.
এখন দেখুন cppreferences সম্পর্কে কি বলে std::same_as
:
std::same_as<T, U>
উপসাগর std::same_as<U, T>
এবং বিপরীত।
এটি মূলত "যদি-এবং-কেবলমাত্র" সম্পর্ক হয়: তারা একে অপরকে বোঝায়। (যৌক্তিক সাম্য)
আমার অনুমান যে এখানে পারমাণবিক সীমাবদ্ধতা রয়েছে std::is_same_v<T, U>
। সংকলকগণ যেভাবে আচরণ করে std::is_same_v
তা তাদের ভাবতে std::is_same_v<T, U>
এবং std::is_same_v<U, T>
দুটি পৃথক বাধা হিসাবে (তারা আলাদা আলাদা সত্তা!) তৈরি করতে পারে। সুতরাং আপনি যদি std::same_as
তাদের মধ্যে একটি ব্যবহার করে বাস্তবায়ন করেন:
template< class T, class U >
concept same_as = detail::SameHelper<T, U>;
তারপরে std::same_as<T, U>
এবং std::same_as<U, T>
বিভিন্ন পরমাণু সীমাবদ্ধতায় "বিস্ফোরিত" হবে এবং সমতুল্য হবে না।
আচ্ছা, সংকলক কেন যত্ন করে?
এই উদাহরণ বিবেচনা করুন :
#include <type_traits>
#include <iostream>
#include <concepts>
template< class T, class U >
concept SameHelper = std::is_same_v<T, U>;
template< class T, class U >
concept my_same_as = SameHelper<T, U>;
// template< class T, class U >
// concept my_same_as = SameHelper<T, U> && SameHelper<U, T>;
template< class T, class U> requires my_same_as<U, T>
void foo(T a, U b) {
std::cout << "Not integral" << std::endl;
}
template< class T, class U> requires (my_same_as<T, U> && std::integral<T>)
void foo(T a, U b) {
std::cout << "Integral" << std::endl;
}
int main() {
foo(1, 2);
return 0;
}
আদর্শভাবে, my_same_as<T, U> && std::integral<T>
সাবুম my_same_as<U, T>
; অতএব, সংকলকটির দ্বিতীয় টেম্পলেট বিশেষীকরণ নির্বাচন করা উচিত, ব্যতীত ... এটি করে না: সংকলকটি একটি ত্রুটি নির্গত করে error: call of overloaded 'foo(int, int)' is ambiguous
।
এর পিছনে কারণ হ'ল যেহেতু my_same_as<U, T>
এবং my_same_as<T, U>
একে অপরকে গ্রাহ্য করে না my_same_as<T, U> && std::integral<T>
এবং my_same_as<U, T>
অতুলনীয় হয়ে যায় ( উপস্থার সম্পর্কের অধীনে আংশিকভাবে অর্ডার করা সীমাবদ্ধতার উপর)।
তবে, যদি আপনি প্রতিস্থাপন
template< class T, class U >
concept my_same_as = SameHelper<T, U>;
সঙ্গে
template< class T, class U >
concept my_same_as = SameHelper<T, U> && SameHelper<U, T>;
কোডটি সংকলন করে।
SameHelper<T, U>
সত্যSameHelper<U, T>
হতে পারে এর অর্থ হতে পারে না।