class C {
using namespace std; // error
};
namespace N {
using namespace std; // ok
}
int main () {
using namespace std; // ok
}
সম্পাদনা করুন : এর পিছনে অনুপ্রেরণা জানতে চান।
class C {
using namespace std; // error
};
namespace N {
using namespace std; // ok
}
int main () {
using namespace std; // ok
}
সম্পাদনা করুন : এর পিছনে অনুপ্রেরণা জানতে চান।
class/struct
। এটি কেবল সহজভাবে অনুমোদিত নয়। তবে গৃহীত উত্তরটি এটিকে অস্বীকার করার জন্য খুব যৌক্তিক যুক্তি নিয়ে আলোচনা করে। অর্থাত্ কোথায় বিবেচনা করতে হবে Hello::World
এবং কোথায় বিবেচনা করতে হবে World
। আশা যে সন্দেহ মুছে।
উত্তর:
আমি ঠিক জানি না, তবে আমার ধারণা বর্গক্ষেত্রে এটিকে অনুমতি দেওয়া বিভ্রান্তির কারণ হতে পারে:
namespace Hello
{
typedef int World;
}
class Blah
{
using namespace Hello;
public:
World DoSomething();
}
//Should this be just World or Hello::World ?
World Blah::DoSomething()
{
//Is the using namespace valid in here?
}
যেহেতু এটি করার কোনও সুস্পষ্ট উপায় নেই, স্ট্যান্ডার্ডটি বলে যে আপনি পারবেন না।
এখন, যখন আমরা নেমস্পেসের স্কোপগুলিতে কথা বলছি তখন এটি কম বিভ্রান্তির কারণ:
namespace Hello
{
typedef int World;
}
namespace Other
{
using namespace Hello;
World DoSomething();
}
//We are outside of any namespace, so we have to fully qualify everything. Therefore either of these are correct:
//Hello was imported into Other, so everything that was in Hello is also in Other. Therefore this is okay:
Other::World Other::DoSomething()
{
//We're outside of a namespace; obviously the using namespace doesn't apply here.
//EDIT: Apparently I was wrong about that... see comments.
}
//The original type was Hello::World, so this is okay too.
Hello::World Other::DoSomething()
{
//Ditto
}
namespace Other
{
//namespace Hello has been imported into Other, and we are inside Other, so therefore we never need to qualify anything from Hello.
//Therefore this is unambiguiously right
World DoSomething()
{
//We're inside the namespace, obviously the using namespace does apply here.
}
}
using namespace Hello;
অন্যান্য অভ্যন্তরের namespace
জন্যও প্রযোজ্য (এবং এর extern
অভ্যন্তরে ফাংশন ঘোষণা করে)।
Hello::World Blah::DoSomething()
বা Blah::World Blah::DoSomething()
(যদি এটি অনুমোদিত হয়ে থাকে) তবে সদস্য ফাংশন সংজ্ঞার ফেরতের ধরণটি ভাষাতে শ্রেণীর পরিসর হিসাবে বিবেচিত হয় না, তাই এটি যোগ্য হতে হবে। শ্রেণীর সুযোগের using
সাথে প্রতিস্থাপনের বৈধ উদাহরণ বিবেচনা করুন typedef Hello::World World;
। সুতরাং সেখানে কোনও আশ্চর্য হওয়া উচিত নয়।
কারণ সি ++ স্ট্যান্ডার্ড এটি পরিষ্কারভাবে নিষেধ করে। সি ++ 03 §7.3.4 থেকে [নেমস্পেস.উডির]:
ব্যবহার-নির্দেশিকা : নেমস্পেস ব্যবহার করে :: opt नेস্টেড-নেম-স্পেসিফায়ার অপ্ট নেমস্পেস-নাম ;
একটি ব্যবহারের নির্দেশিকা শ্রেণীর স্কোপগুলিতে উপস্থিত হবে না তবে এটি নামস্থান স্কোপ বা ব্লক স্কোপে প্রদর্শিত হতে পারে। [দ্রষ্টব্য: কোনও ব্যবহার-নির্দেশিকায় নেমস্পেস-নাম সন্ধান করার সময়, কেবলমাত্র স্থানের নাম বিবেচনা করা হয়, দেখুন 3.4.6। ]
সি ++ স্ট্যান্ডার্ড কেন এটি নিষিদ্ধ করে? আমি জানি না, আইএসও কমিটির কোনও সদস্যকে জিজ্ঞাসা করুন যা ভাষার মান অনুমোদন করেছে।
আমি বিশ্বাস করি যে যুক্তিটি সম্ভবত এটি বিভ্রান্তিকর হবে। বর্তমানে, ক্লাস স্তর সনাক্তকারীকে প্রক্রিয়া করার সময়, অনুসন্ধান প্রথমে শ্রেণীর ক্ষেত্র এবং তারপরে ঘেরের নামস্থানতে অনুসন্ধান করবে। using namespace
শ্রেণি পর্যায়ে অনুমতি দেওয়া এখন কীভাবে প্রদর্শন করা হয় তার বেশ কিছু পার্শ্ব প্রতিক্রিয়া থাকতে পারে। বিশেষত, নির্দিষ্ট শ্রেণির ক্ষেত্রটি পরীক্ষা করা এবং ঘেরের নামস্থান পরীক্ষা করার মধ্যে এটির মাঝে মাঝে সঞ্চালন করতে হবে। এটি হ'ল: 1) বর্গ স্তর এবং ব্যবহৃত নেমস্পেস স্তরের লুকোচুয়ালগুলি মার্জ করুন, ২) বর্গক্ষেত্রের পরে ব্যবহৃত নেমস্পেসটি অনুসন্ধান করুন তবে অন্য কোনও শ্রেণির ক্ষেত্রের আগে, 3) বদ্ধ নামকরণের ঠিক আগে ব্যবহৃত নেমস্পেসটি অনুসন্ধান করুন। 4) লুকোচুরিটি এনকোলেসিং নেমস্পেসের সাথে একত্রিত করা হয়েছে।
।
namespace A {
void foo() {}
struct B {
struct foo {};
void f() {
foo(); // value initialize a A::B::foo object (current behavior)
}
};
}
struct C {
using namespace A;
struct foo {};
void f() {
foo(); // call A::foo
}
};
।
namespace A {
void foo() {}
}
void bar() {}
struct base {
void foo();
void bar();
};
struct test : base {
using namespace A;
void f() {
foo(); // A::foo()
bar(); // base::bar()
}
};
।
namespace A {
void foo( int ) { std::cout << "int"; }
}
void foo( double ) { std::cout << "double"; }
struct test {
using namespace A;
void f() {
foo( 5.0 ); // would print "int" if A is checked *before* the
// enclosing namespace
}
};
using
নাম স্থান পর্যায়ে ঘোষণাটি প্রয়োগ করে । এটি এতে কোনও নতুন মান যুক্ত করবে না, তবে অন্যদিকে সংকলক বাস্তবায়নকারীদের জন্য অনুসন্ধানকে জটিল করবে। কোডটি যেখানে অনুসন্ধানের সূত্রপাত করেছে সেখান থেকে নেমস্পেস শনাক্তকারী অনুসন্ধান এখন স্বতন্ত্র। শ্রেণীর ভিতরে যখন, শ্রেনীর স্কোপগুলিতে যদি সনাক্তকারী সনাক্ত না করে তবে এটি নামফলন অনুসন্ধানে ফিরে যাবে, তবে এটি ঠিক একই নাম স্থানটি অনুসন্ধান যা কোনও ফাংশন সংজ্ঞাতে ব্যবহৃত হয়, নতুন রাষ্ট্র বজায় রাখার দরকার নেই। যখন using
ঘোষণাটি নেমস্পেস স্তরে পাওয়া যায়, ব্যবহৃত নেমস্পেসের বিষয়বস্তু সকলের জন্য সেই নেমস্পেসে আনা হয় জায়গার সাথে জড়িত অনুসন্ধানের । যদিusing namespace
শ্রেণি পর্যায়ে অনুমোদিত ছিল, যেখানে অনুসন্ধানটি ট্রিগার করা হয়েছে তার উপর ভিত্তি করে ঠিক একই নেমস্পেসের নেমস্পেস অনুসন্ধানের জন্য আলাদা আলাদা ফলাফল হতে পারে এবং অতিরিক্ত মূল্য ছাড়াই অনুসন্ধানের বাস্তবায়নকে আরও জটিল করে তুলবে।যাইহোক, আমার সুপারিশটি হ'ল ঘোষণাটি মোটেই কাজে লাগানো using namespace
নয়। এটি সমস্ত নেমস্পেসের বিষয়বস্তু মাথায় না রেখেই যুক্তিযুক্ত কোডটিকে সহজ করে তোলে।
using
বিদ্যমান রয়েছে তার আশেপাশে নকশা করা যেতে পারে । গভীর নেস্টেড দীর্ঘস্থানে জায়গাগুলি উদ্দেশ্যমূলকভাবে ঘোষণা করে। যেমন glm
তা করে এবং ক্লায়েন্ট যখন ব্যবহার করে তখন বৈশিষ্ট্যগুলি সক্রিয় / উপস্থাপন করতে একাধিক কৌশল ব্যবহার করে using
।
using namespace std::placeholders
। cf en.cppreferences.com/w/cpp/utility/functional/bind
namespace ph = std::placeholders;
এটি সম্ভবত উন্মুক্ততা বনাম বন্ধনের কারণে অনুমোদিত নয় ।
ক্লাসে নেমস্পেসগুলি আমদানি করা মজার ক্ষেত্রে এরকম হতে পারে:
namespace Foo {}
struct Bar { using namespace Foo; };
namespace Foo {
using Baz = int; // I've just extended `Bar` with a type alias!
void baz(); // I've just extended `Bar` with what looks like a static function!
// etc.
}
namespace Foo
কাঠামোটির সংজ্ঞাটির ভিতরে থাকা সমস্ত কোডের জন্য অনুসন্ধানের অর্ডারে যুক্ত হওয়া যাক struct Bar
, যেমন প্রতিটি লাইনটি প্রতিটি ইনলাইন সদস্য ফাংশন বডিতে রাখার মতো, তবে এটি ব্রেস-বা-সমান আরম্ভকারীদের জন্যও সক্রিয় থাকবে ইত্যাদি ইত্যাদি তবে এটি এখনও থাকবে ক্লোজিং ব্রেসে মেয়াদ শেষ হবে, using namespace
সদস্য ফাংশন বডির ভিতরে একই । এখন দুর্ভাগ্যক্রমে এনকোলেসিং নেমস্পেসকে দূষিত না করে কোনও ব্রেস-বা সমমান ইনিশিয়ালাইজারে কোয়েনিগ-সহ-ফ্যালব্যাক লুকের ব্যবহার করার কোনও উপায় বলে মনে হচ্ছে না।
আমি মনে করি এটি ভাষার একটি ত্রুটি। আপনি নীচে workaround ব্যবহার করতে পারেন। এই কর্মসূচির কথা মাথায় রেখে, ভাষা পরিবর্তন করা হবে তখন মামলার বিরোধের সমাধানের নিয়মের পরামর্শ দেওয়া সহজ।
namespace Hello
{
typedef int World;
}
// surround the class (where we want to use namespace Hello)
// by auxiliary namespace (but don't use anonymous namespaces in h-files)
namespace Blah_namesp {
using namespace Hello;
class Blah
{
public:
World DoSomething1();
World DoSomething2();
World DoSomething3();
};
World Blah::DoSomething1()
{
}
} // namespace Blah_namesp
// "extract" class from auxiliary namespace
using Blah_namesp::Blah;
Hello::World Blah::DoSomething2()
{
}
auto Blah::DoSomething3() -> World
{
}
using namespace
। সি # তেমন কিছু মঞ্জুরি দেয় তবে কেবল ফাইল স্কোপে। সি ++ এরusing namespace
সাহায্যে আপনি একটি নামের স্থানকে অন্যটিতে অন্তর্ভুক্ত করতে পারবেন।