সি ++ এ "ইউজিং" ব্যবহার করবেন নাকি এড়িয়ে চলবেন?


17

ADL এর কারণে সাবলেটলি আলাদা সিমানটিক ছাড় করা হচ্ছে, আমার সাধারণত কীভাবে ব্যবহার করা উচিত usingএবং কেন? এটি কি পরিস্থিতি নির্ভর (যেমন শিরোনাম যা #includeডি বনাম উত্স ফাইল যা হবে না)?

এছাড়াও, আমি পছন্দ করব ::std::নাকি std::?

  1. নামস্থান স্তর using namespace:

    using namespace std;
    
    pair<string::const_iterator, string::const_iterator>
    f(const string &s) {
        return make_pair(s.begin(), s.end());
    }
    
  2. সম্পূর্ণরূপে সুস্পষ্ট:

    std::pair<std::string::const_iterator, std::string::const_iterator>
    f(const std::string &s) {
        return std::make_pair(s.begin(), s.end());
    }
    
  3. নাম-স্তরের ব্যবহার-ঘোষণাগুলি:

    using std::pair;
    using std::string;
    
    pair<string::const_iterator, string::const_iterator>
    f(const string &s) {
        return make_pair(s.begin(), s.end());
    }
    
  4. ফাংশন-স্থানীয় ব্যবহার-ঘোষণা:

    std::pair<std::string::const_iterator, std::string::const_iterator>
    f(const std::string &s) {
        using std::make_pair;
        return make_pair(s.begin(), s.end());
    }
    
  5. ফাংশন-স্থানীয় using namespace:

    std::pair<std::string::const_iterator, std::string::const_iterator>
    f(const std::string &s) {
        using namespace std;
        return make_pair(s.begin(), s.end());
    }
    
  6. অন্যকিছু?

এটি প্রি-সি ++ ১৪ ধরে নিচ্ছে এবং এভাবে কোনও রিটার্ন-টাইপ-ছাড় ছাড় নয় auto


2
প্রারম্ভিক পয়েন্টের জন্য stackoverflow.com/questions/1265039/ using-std-namespace দেখুন ।
এপ্রোগ্রামার

@ প্রোগ্রামার: আহ, লিঙ্কটির জন্য ধন্যবাদ, যা আমার প্রশ্নের অংশের উত্তর দেয়। :) এখনও ::std::বনাম সম্পর্কে সম্পর্কে ভাবছি std::
ব্যবহারকারী541686

4
আমি stdযদিও দ্বিতীয় ছাড়া ব্যবহার করছি । একটি স্ট্যান্ডার্ড নেমস্পেস সংজ্ঞায়িত কেউ সমস্যার জন্য জিজ্ঞাসা করছে (এবং সম্ভবত সুবিধাটি পেতে সন্ধান করছেন যে বেশিরভাগ লোকেরা ব্যবহার করছেন stdএবং না ::std)।
এপ্রোগ্রামার

উত্তর:


25

usingশিরোনাম ব্যবহার করা থেকে বিরত থাকুন, কারণ এটি নামের জায়গাগুলির উদ্দেশ্যকে ভঙ্গ করে।

এটি উত্স ফাইলগুলিতে ব্যবহার করা ঠিক আছে তবে আমি এখনও কিছু ক্ষেত্রে এড়াতে চাই (উদাহরণস্বরূপ using std)।

তবে আপনি যদি নেস্টেড নেমস্পেসগুলি পেয়ে থাকেন তবে ঠিক আছে:

namespace A {
namespace B {
namespace C {
class s;
} // C
} // B
namespace D{
using B::C::s;
} // D
} // A

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

লোকেরা iostreams, স্ট্রিং ইত্যাদি ব্যবহার করে এগিয়ে যেতে চায়। তারা স্ট্যান্ড টাইপ করতে চায় না :: প্রতিটি সময় তারা কোনও জিনিস ব্যবহার করতে চায় বা তাদের কোডের সামনে রাখার জন্য আরও একটি বয়লারপ্লেট মনে রাখতে হয়, যা তারা ভুলে গেলে কম-সহায়ক ত্রুটির কারণ হয়ে দাঁড়ায় । :(
কলেন

টাইপিড স্টাড :: স্ট্রিং স্ট্রিংয়ের মতো কিছু হবে; বিকল্প হতে পারে?
জর্জিও

1
@ কোলেন: এই দরিদ্র আত্মারা ব্যবহার করতে পারে using std::coutএবং বন্ধুবান্ধব, তবে এটি coutইতিমধ্যে একটি ভয়াবহ দীর্ঘ নাম নয়।
বেনিয়ামিন বান্নিয়ার

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

11

সোর্স ফাইলে একটি ইউজিং স্টেটমেন্ট রাখার সময় দয়া করে আপনার প্রয়োজনীয় জিনিসগুলি টানুন। এই ক্ষেত্রে:

using std::string;
using std::ostringstream;

এখানে সমস্যাটি যদি আপনি করেন তবে

using namespace std;

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


বিকল্পভাবে, আপনি using namespaceসমস্যাটি এড়িয়ে কেবল কোনও ফাংশনের সুযোগে করতে পারেন ।
ট্যামস সেজেলি

2
@ ফিশ - আসলে ফাংশন স্কোপে 'নেমস্পেস' ব্যবহার করা সমস্যাটিকে এড়ায় না, এটি কেবল স্থানটি সীমাবদ্ধ করে যেখানে জিনিসগুলি ভুল হতে পারে। এবং যদি আপনি প্রতিটি কার্যক্রমে 'নেমস্পেস' ব্যবহার করে শেষ করেন তবে এটি বিশ্বব্যাপী এটি করা থেকে আলাদা নয়।
মাইকেল কোহেন

যদিও সি ++ প্রকৃতপক্ষে কোনওটিকে ফাংশন স্তরে প্রকারগুলি প্রকাশ করার অনুমতি দেয় তবে এটি কোনও সাধারণ বিষয় নয়; এগুলি ছাড়াও, সংকলক আউটপুট থেকে সম্ভাব্য নাম সংঘর্ষগুলি স্পষ্ট করা সহজ (তবে আপনি ঠিক বলেছেন যে এটি তাদের প্রতিরোধ করে না)।
ট্যামস সেজেলি

2

ভিজোভিচ ইঙ্গিত হিসাবে, usingএকটি শিরোনাম ফাইলে ব্যবহার করবেন না । usingএকটি শিরোনাম ফাইলটিতে উত্স ফাইলটি প্রত্যাশা না করে এমনভাবে বর্তমান সংকলন ইউনিটকে (.cpp ফাইল) প্রভাবিত করে।

using namespaceএকটি উত্স ফাইল এড়াতে হয়। এটি প্রতিটি চিহ্নকে উত্স ফাইল হিসাবে একই সুযোগে নিয়ে আসে। আপনি যদি নেমস্পেস থেকে নির্দিষ্ট চিহ্ন ব্যবহার করেন তবে আপনি কী করছেন তা আপনার পাঠকদের কাছে এটি আরও স্পষ্ট।


2
ব্যবহারিক উদ্বেগ হিসাবে, যদি না আপনার কোডটি সাধারণভাবে ব্যবহৃত নামগুলিকে ওভাররাইড করে না, আমি প্রতিটা বস্তুর সাথে using namespace JoystickModuleসংযুক্তের চেয়ে একটি .cpp ফাইলের শুরুতে দেখতে চাই JoystickModule::
অ্যালেক্স পি

@ অ্যালেক্সপি: ঠিক আমি এটিই করি। usingআমার নিজের নামের জায়গার জন্য একটি বিবৃতি আমি বর্তমানে কাজ করছি এবং অন্য সব কিছুই নামগতিতে থাকে।
বেনিয়ামিন ক্লোস্টার

আমার "নামস্থান থেকে নির্দিষ্ট চিহ্ন ব্যবহার করুন" এর বিশদ বিবরণ করা উচিত। প্রতিটি ব্যবহারে প্রতিটি প্রতীককে উপসর্গ করার পরিবর্তে, যা পাঠযোগ্যতার সাথে সহায়তা করে না, আমি সুস্পষ্ট প্রতীক উত্তোলন ব্যবহার করতে পছন্দ করি। using SomeNameSpace::SomeSymbol। এটি নেমস্পেস থেকে বর্তমানের স্কোপটিতে প্রতিটি প্রতীক স্থানান্তর এড়াতে পারে।
বিল ডোর 16

0

লিখন usingশিরোলেখ মধ্যে সব ধরণের তৈরি করতে ভাল উপায় কদর্য এবং ডিবাগ করা অসম্ভব বাগ। এটি করবেন না

using namespace XYZউত্স ফাইলে লেখা কিছুটা ভাল তবে এখনও আপনাকে অসংখ্য মাথা ব্যথার কারণ হতে পারে। সুরক্ষিত উপায় স্পষ্টভাবে কি উদাঃ ব্যবহার করছেন উল্লেখ করা হয় using Foo::Bar

ধরা যাক আপনার নিম্নলিখিত বার্কপিপি রয়েছে:

//Bar.cpp
using namespace Foo;
namespace
{
    double increment(double v) { return (v + 1); }
}

void Bar::someFunction()
{
    //...
    int currentIndex = 0;
    int nextIndex = increment(currentIndex);
    //...
}

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

শেষ পর্যন্ত আপনি কারণটি আবিষ্কার করেছেন:
আপনি (পরোক্ষভাবে) Foo.hকোথাও অন্তর্ভুক্ত করবেন । Foo নেমস্পেসের ফাইলগুলিতে একটি নতুন ফাংশন যুক্ত করা হয়েছিল:

//Foo.h
namespace Foo
{
    //...
    int& increment(int& v) { v += 1; return v; };
    //...
}

increment(int)আপনার ফাংশনের চেয়ে কোন সন্দেহের চেয়ে ভাল মিল increment(double)- তাই এখন পরিবর্তে Foo::increment()ফাংশন বলা হয় Bar::someFunction()। উপস।

(এবং আপনি যদি usingশিরোনামগুলিতে লিখতেন যা আপনার অন্তর্ভুক্ত গাছের using namespace Fooখুব ভাল কোনও জায়গায় থাকতে পারে ...)

সুতরাং ... না কোনো লিখতে usingশিরোলেখ মধ্যে, এবং এছাড়াও লেখার সতর্ক হতে using namespaceউৎস ফাইলের মধ্যে।

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