সি ++ মানচিত্রের অ্যাক্সেস ছাড়ার যোগ্যতা (কনস্ট্যান্ট)


113

নিম্নলিখিত কোড বলছেন যে যেমন মানচিত্র ক্ষণস্থায়ী constমধ্যে operator[]পদ্ধতি পরিত্যাগ কোয়ালিফায়ার:

#include <iostream>
#include <map>
#include <string>

using namespace std;

class MapWrapper {
public:
    const int &get_value(const int &key) const {
        return _map[key];
    }

private:
    map<int, int> _map;
};

int main() {
    MapWrapper mw;
    cout << mw.get_value(42) << endl;
    return 0;
}

মানচিত্র অ্যাক্সেসে ঘটে এমন সম্ভাব্য বরাদ্দের কারণে এটি কি? মানচিত্র অ্যাক্সেস সহ কোনও ক্রিয়াকলাপ কনস্ট হিসাবে ঘোষণা করা যায় না?

MapWrapper.cpp:10: error: passing ‘const std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >’ as ‘this’ argument of ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = int, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, int> >]’ discards qualifiers


কেবল একটি নটপিক, তবে মেগাওয়াটটিকে কেবল ম্যাপওয়্যার্পার এমডব্লু হিসাবে ঘোষণা করা যেতে পারে;
luke

ভাল পয়েন্ট - আমি কয়েকটি ভাষায় লিখি তাই আমি তাদের জুড়ে সিনট্যাক্সটি স্বাভাবিক করার চেষ্টা করি যাতে সেগুলি আমার মাথার মধ্যে খাপ খায়। :)
সিডলারি

আমি যে প্রশংসা করতে পারেন। তবে সাবধান থাকুন, এর মতো ক্ষেত্রে আপনার একটি অতিরিক্ত অবজেক্ট নির্মাণ এবং অ্যাসাইনমেন্ট রয়েছে যা প্রয়োজনীয় নয়।
luke

আরেকটি ভাল পয়েন্ট - ডিফল্ট অ্যাসাইনমেন্ট অপারেটরের উপর নির্ভর করা জনসাধারণের উদাহরণগুলির জন্য ভাল অভ্যাস নয়। ;)
সিডলারি

উত্তর:


152

std::mapএর operator []হিসাবে ঘোষিত হয় না constএবং এর আচরণের কারণে এটি হতে পারে না:

টি ও অপারেটর [] (কনট কী এবং কী)

কী এর সমতুল্য কীতে ম্যাপ করা মানটির একটি রেফারেন্স প্রদান করে, যদি এমন কী ইতিমধ্যে উপস্থিত না থাকে তবে সন্নিবেশ সম্পাদন করে।

ফলস্বরূপ, আপনার ফাংশনটি ঘোষিত হতে পারে না const, এবং মানচিত্রটি ব্যবহার করুন operator[]

std::mapএরfind() কার্যকারিতা আপনাকে মানচিত্র পরিবর্তন না করে কোনও কী সন্ধান করতে দেয়।

find()একটি ফেরৎ iterator, অথবা const_iteratorএকটি থেকে std::pairউভয় কী (ধারণকারী .first) এবং মান ( .second)।

সি ++ 11, এছাড়াও আপনি ব্যবহার করতে পারে at()জন্য std::map। যদি উপাদান উপস্থিত না থাকে তবে std::out_of_rangeবিপরীতে, ফাংশনটি একটি ব্যতিক্রম ছুঁড়ে operator []


8
অতিরিক্তভাবে: VALUE = map.find (KEY) -> দ্বিতীয়; আমাকে শিখতে হয়েছিল যে 'ফাইন্ড ()' পুনরুক্তি প্রদান করে, যা টাইপ জোড়া।
ফ্লিপএমসিএফ

5
আমি যোগ করতে চাই যে এখন সি 11 এ আপনি ব্যবহার করতে পারেন: স্টাড :: ম্যাপ :: এ (কী) এবং পুনরাবৃত্তকারীটিকে এড়াতে।
জুয়ান বেসা

3
মজাদার. আমার মনে হয় সি ++ লভ্যালু operator[](উদাঃ foo[bar] = baz) এবং মূল্য operator[](যেমন x = foo[bar]) এর মধ্যে পার্থক্য করবে - পরবর্তীটি অবশ্যই কনস্ট হতে পারে।
ক্লাদিউ

15

যেহেতু operator[]কনস্ট-কোয়ালিফাইড ওভারলোড নেই, তাই এটি কনস্ট-কোয়ালিটিড ফাংশনে নিরাপদে ব্যবহার করা যাবে না। এটি সম্ভবত কারণ বর্তমান ওভারলোডটি প্রত্যাবর্তন এবং মূল মান নির্ধারণ উভয়ের লক্ষ্য নিয়ে নির্মিত হয়েছিল।

পরিবর্তে, আপনি ব্যবহার করতে পারেন:

VALUE = map.find(KEY)->second;

অথবা, সি ++ 11 এ আপনি at()অপারেটরটি ব্যবহার করতে পারেন :

VALUE = map.at(KEY);

map.find(KEY)->second; মানচিত্রের মানগুলি যখন স্ট্রিং থাকে তখন এটি অনিরাপদ। যখন KEY পাওয়া যায় না তখন এটি আবর্জনা মুদ্রণের ঝোঁক দেয়।
সিয়াম

1
এটি সঠিকভাবে ব্যাখ্যা করা উত্তর যা পয়েন্টে যায়। গতকাল আমি অনুরূপ কেসের সাথে কী চলছে তা বের করার চেষ্টা করতে 2 ঘন্টা ব্যয় করেছি। আমরা কি একমত হতে পারি যে ত্রুটি বার্তাটি সর্বোত্তমভাবে বিভ্রান্তিকর? যদি এটা শব্দ 'এই' এবং তৈরি রেফারেন্স ছিল না আমি পথ আরো স্পষ্ট হতে পারে const-অন্তরীপ পরিবর্তে আরো জেনেরিক কোয়ালিফায়ার
কার্নিকার

11

আপনি operator[]কোনও মানচিত্রে ব্যবহার করতে পারবেন না যা constসেই পদ্ধতির constমতো নয় এটি আপনাকে মানচিত্রটি সংশোধন করার অনুমতি দেয় (আপনি নির্ধারণ করতে পারেন _map[key])। findপরিবর্তে পদ্ধতিটি ব্যবহার করে দেখুন ।


1
ব্যাখ্যা করার মাধ্যমে: মানচিত্রটির অপারেটর [] কী করা উচিত যদি কীটি বিদ্যমান না থাকে? মানচিত্রটি যদি অবিচ্ছিন্ন হয় তবে কীটি ডিফল্ট-নির্মিত মান সহ যুক্ত করা হয়। যদি মানচিত্রের কনস্ট, অপারেটর দ্বারা কী ফিরিয়ে দেওয়া যায় []? Key চাবিটির কোনও মূল্য নেই।

এটি সঠিকভাবে ব্যাখ্যা করা উত্তর যা পয়েন্টে যায়। গতকাল আমি অনুরূপ কেসের সাথে কী চলছে তা বের করার চেষ্টা করতে 2 ঘন্টা ব্যয় করেছি। আমরা কি একমত হতে পারি যে ত্রুটি বার্তাটি সর্বোত্তমভাবে বিভ্রান্তিকর? যদি এটা শব্দ 'এই' এবং তৈরি রেফারেন্স ছিল না আমি পথ আরো স্পষ্ট হতে পারে const-অন্তরীপ পরিবর্তে আরো জেনেরিক কোয়ালিফায়ার
কার্নিকার

7

জিসিসির শিরোনামের কয়েকটি নতুন সংস্করণ (আমার মেশিনে ৪.১ এবং ৪.২) মানহীন সদস্য ফাংশন ম্যাপ :: এ () রয়েছে যা কনস্টেড হিসাবে ঘোষিত হয়েছে এবং স্ট্যান্ড :: আউট_ অফ_আরঞ্জি যদি মানচিত্রে না থাকে তবে।

const mapped_type& at(const key_type& __k) const

ফাংশনের মন্তব্যের একটি রেফারেন্স থেকে, এটি স্ট্যান্ডার্ড লাইব্রেরিতে একটি নতুন সদস্য ফাংশন হিসাবে প্রস্তাবিত হয়েছে বলে মনে হয়।


আমি অনুমান করি যে এটুকু কোচ। এ-ফাংশনটি আসন্ন মানটির অংশ, তবে আমি বর্তমানের কোনওটিতে () পাই না।
সেবাস্তিয়ান মাচ

'এট' সি ++ 11 এর অংশ।
Étienne

0

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

আপনি যদি আন্ডারস্কোর ব্যবহার করতে চান তবে এটি শুরুতে নয়, শেষে রাখুন। আপনি সম্ভবত এই ভুলটি করেছেন কারণ আপনি কিছু মাইক্রোসফ্ট কোড এটি করতে দেখেছেন। মনে রাখবেন, তারা তাদের নিজস্ব সংকলক লিখেছেন, যাতে তারা এটি থেকে দূরে যেতে সক্ষম হতে পারে। তবুও, এটি একটি খারাপ ধারণা।

অপারেটর [] কেবল একটি রেফারেন্সই দেয় না, এটি প্রকৃতপক্ষে মানচিত্রে এন্ট্রি তৈরি করে। সুতরাং আপনি কেবল একটি ম্যাপিং পাচ্ছেন না, যদি কিছুই না থাকে তবে আপনি একটি তৈরি করছেন। আপনি যা ইচ্ছা করেছিলেন তা নয়।


5
সম্পর্কে আপনার বক্তব্য _ঠিক ভুল। দুটি আন্ডারস্কোর ( __example) বা শনাক্তকারীরা একটি আন্ডারস্কোর এবং মূলধন বর্ণ ( _Example) দিয়ে শুরু করে সনাক্তকারীগুলি সংরক্ষিত থাকে। _exampleসংরক্ষিত নেই
ইথান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.