অনুলিপি নির্মাণকারীতে সি ++ নামের স্থানের সংঘর্ষ


33

আমার কাছে নিম্নলিখিত কোড রয়েছে:

namespace A {
    struct Foo {
        int a;
    };
}

struct Foo {
    int b;
};

struct Bar : public A::Foo {
    Bar(Foo foo) {
        c = foo.b;
    }
    int c;
};

সি ++ সংকলকগুলি "সি = foo.b" এ অভিযোগ করে কারণ এ :: ফু এর কোনও সদস্য নাম বি নেই। আমি যদি এর সাথে বার প্যারামিটারের ধরনটি পরিবর্তন করি: ফুও এটি কাজ করে।

আমার প্রশ্ন হ'ল এই আচরণের পিছনে যুক্তি কি (আমি মনে করি যে উত্তরাধিকারটি বারকে একটি নামস্থানে প্রবেশ করে তবে এই তত্ত্বটিকে সমর্থন করার জন্য আমি কোনও দলিল খুঁজে পাই না।


8
আমি মনে করি এটি যুক্তি নির্ভর নির্ভর অনুসন্ধান সম্পর্কিত। আমি "ভাষা-আইনজীবী" ট্যাগ করেছি কারণ আমি মনে করি যে আপনি উত্তরগুলির পরে ভাষাটির মানটি উল্লেখ করেছেন। এবং খুব ভাল প্রথম প্রশ্ন! এটি সব সার্থক করে তোলে।
বাথশেবা

এটি নেমস্পেসে প্রবেশ করে না A, যা আপনি দেখতে পাচ্ছেন যে আপনি Barঅন্য কাঠামো থেকে উত্তরাধিকার সূত্রে দেওয়া হয়েছে কিনা A। তারপরে কোনও দ্বিধা নেই। এটা তোলে উত্তরাধিকার থেকে সবকিছু যোগ আরো ভালো হয় A::Fooকরার Barরেজল্যুশন সহ Fooকরার A::Foo। দুঃখিত, আমি সত্যিই এটি আরও সুনির্দিষ্টভাবে প্রকাশ করতে পারি না।
n314159

@ বাথশেবা আপনার অর্থ কি ফাংশনের নামগুলি (বা ফাংশন টেম্পলেটগুলির নাম) বা টেমপ্লেটগুলিতে নির্ভরশীল নামগুলি অনুসন্ধানের জন্য আর্গুমেন্ট টাইপের নির্ভরশীল নাম অনুসন্ধান?
কৌতূহলী

উত্তর:


22

প্রতিটি শ্রেণীর সদস্য হিসাবে এটিতে এর নাম সংযোজন করা হয়। সুতরাং আপনি নাম করতে পারেন A::Foo::Foo। একে ইনজেকশন শ্রেণীর নাম বলা হয়।

[বর্গ]

2 একটি শ্রেণি-নাম স্কোপটিতে sertedোকানো হয় যেখানে শ্রেণি-নামটি দেখার সাথে সাথে এটি ঘোষণা করা হয়। শ্রেণি-নামটিও বর্গের মধ্যেই isোকানো হয়; এটি ইনজেকশন-শ্রেণি-নাম হিসাবে পরিচিত। অ্যাক্সেস চেকিংয়ের উদ্দেশ্যে, ইনজেক্টেড-শ্রেণি-নামটি এমন আচরণ করা হয় যেন এটি কোনও পাবলিক সদস্যের নাম।

[Basic.lookup]

3 শ্রেণিটির ইনজেকশন-শ্রেণি-নামটি নাম গোপন এবং অনুসন্ধানের উদ্দেশ্যে সেই শ্রেণীর সদস্য হিসাবেও বিবেচনা করা হয়।

যেহেতু আর্গুমেন্ট প্রকারের অযোগ্য নাম অনুসন্ধান শ্রেণীর স্কোপ থেকে শুরু হয় Bar, এটি সেখানে কোনও সদস্যের জন্য অ্যাকাউন্ট করার জন্য এটি তার বেস শ্রেণীর আওতায় থাকবে। এবং এটি A::Foo::Fooএকটি প্রকারের নাম হিসাবে খুঁজে পাবেন ।

আপনি যদি বিশ্বব্যাপী প্রকারের নামটি ব্যবহার করতে চান তবে কেবল এর আশেপাশের (গ্লোবাল) নেমস্পেস দ্বারা এটি যোগ্যতা অর্জন করুন।

Bar(::Foo foo) {
    c = foo.b;
}

যা সম্পূর্ণরূপে যোগ্য অনুসন্ধানে এমন একটি সুযোগে করছে যেখানে ইনজেকশনের শ্রেণীর নাম উপস্থিত হয় না।

একটি অনুসরণের জন্য "কেন" প্রশ্ন দেখুন


5
@ টেডলাইংমো - এডিএল ফাংশন কলগুলির সাথে ঘটে, সেই নির্দিষ্ট প্যাসেজগুলিতে প্রাসঙ্গিক কিছুই নয়।
স্টোরি টেলার - আনস্ল্যান্ডার মনিকা

ওকি, আমি পড়ছিলাম এবং নিশ্চিত ছিল না। ধন্যবাদ!
টেড লিংগো

3
এটি অত্যন্ত কৌতুকপূর্ণ দিকে নিয়ে যায় struct Bar:: A::Foo::Foo::Foo::Foo::Foo {}; তবে এমন প্রসঙ্গ রয়েছে যেখানে নির্মাতাকেA::Foo::Foo মনোনীত করে এবং সেখানে Fooআপনি চান যতগুলি যুক্ত করা চালিয়ে যেতে পারবেন না । এই সত্যটি অনুরূপ (কিন্তু একটি সম্পূর্ণ ভিন্ন প্রক্রিয়া সহ) যে আপনি একটি ফাংশন কল করতে পারেন fএই ভাবে: (************f)()
এপ্রোগ্রামার

@ এপ্রোগ্রামার - সত্যই। এবং এক আরও মজাদার উদাহরণ নির্মাণ করতে পারেন ।
স্টোরি টেলার - আনস্ল্যান্ডার মনিকা

এই উত্তরটি অবশ্যই "কী" ব্যাখ্যা করে। "কেন" যুক্ত করার জন্য এটি উন্নত করা যেতে পারে? হিসাবে হিসাবে, এই বিধি উদ্দেশ্য কি? কোনটি ব্যবহারের ক্ষেত্রে এটি উন্নতি করে বা সম্ভব করে?
ডেভিডবাক

2

একটি সম্পূর্ণ উত্তর নয়, কেবল কোড যা দেখায় (যেহেতু এটি সংকলন করে) যা Barপ্রবেশ করে না namespace A। আপনি দেখতে পাচ্ছেন যে উত্তরাধিকার সূত্রে প্রাপ্ত হওয়ার A::Foo1সময় অস্পষ্টতার সাথে কোনও সমস্যা নেই Fooযা এই উত্তরাধিকার Barপ্রবেশ করতে দিলে তার থেকে আলাদা হবে A

namespace A {
    struct Foo {
        int a;
    };

    struct Foo1 {
        int a;
    };
}

struct Foo {
    int b;
};

struct Bar : public A::Foo1 {
    Bar(Foo foo) {
        c = foo.b;
    }
    int c;
};
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.