मेरे पास एक Container
वर्ग है जो साझा पॉइंटर्स के वेक्टर को स्टोर करने के लिए है। जब भी कोई आइटम Container
में जोड़ा जाता है, तो मैं चाहता हूं कि वह उस आइटम का स्वामित्व ग्रहण करे। दूसरे शब्दों में, जब Container
का पुनर्निर्माण किया जाता है, तो उसके अंदर के सभी तत्वों को भी विघटित किया जाना चाहिए।
template <typename T>
class Container
{
private:
const std::vector<std::shared_ptr<T>> vec_;
public:
void append(std::shared_ptr<T> item)
{
vec_.push_back(std::move(item));
}
void printElements()
{
for (int i = 0; i < vec_.size(); i++) { std::cout << vec_[i] << std::endl; }
}
};
int main(int argc, char** argv) {
std::unique_ptr<Container<std::string>> c = std::make_unique<Container<std::string>>();
c->append(std::make_shared<std::string>("hello"));
return 0;
}
समस्या यह है कि, मुझे vec_.push_back(std::move(item))
पर निम्न त्रुटि मिलती है।
No matching member function for call to 'push_back'
मुझे यकीन नहीं है कि यह त्रुटि क्यों हो रही है।
1 उत्तर
मूल उत्तर:
आपका std::vector
, vec_
const
है। मुझे लगता है कि push_back()
जैसी किसी भी विधि को जबरदस्ती हटा या अक्षम कर देगा, जो कॉन्स्ट वेक्टर को संशोधित करने का प्रयास करता है।
अतिरिक्त जोड़े गए 10 मई 2020:
मुझे लगता है कि इस टिप्पणी पर @Carpetfizz से उनके प्रश्न के तहत टिप्पणियों में भी विस्तार करना उचित है:
@GabrielStaples धन्यवाद,
const
को हटाकर चाल चली। मैंने सोचा था किconst
केवल वेक्टर_ के पुन: असाइनमेंट के खिलाफ सुरक्षित है लेकिन इसे उत्परिवर्तित करने की अनुमति है?
मेरी प्रतिक्रिया:
नहीं,
const
यहां वेक्टर की सामग्री पर लागू होता है। सदिश एक सूचक नहीं है, लेकिन आप जिसके बारे में बात कर रहे हैं, वह सूचक के साथ किया जा सकता है, सूचक कोconst
की सामग्री के बजाय जो इसे इंगित करता हैconst
। साथ ही,const
औरmutable
विपरीत हैं। एक दूसरे को पूर्ववत करता है। आप दोनों एक ही समय में प्रभावी नहीं हो सकते। परिभाषा के अनुसार, कुछ स्थिर अपरिवर्तनीय (अपरिवर्तनीय) है, और कुछ परिवर्तनीय गैर-स्थिर है।
और कोई कैसे एक पॉइंटर कास्ट बना सकता है, लेकिन इसकी सामग्री को नहीं जो यह इंगित करता है?
सबसे पहले, मूल कोड पर विचार करें (कुछ मामूली संशोधनों/सुधारों के साथ मैंने इसे किया था):
इसे स्वयं यहां ऑनलाइन चलाएं: https://onlinegdb.com/SyMqoeU9L
1) cpp_template_const_vector_of_smart_ptrs_test_BEFORE.cpp:
#include <iostream>
#include <memory>
#include <vector>
template <typename T>
class Container
{
private:
// const std::vector<std::shared_ptr<T>> vec_; // does NOT work
std::vector<std::shared_ptr<T>> vec_; // works!
public:
void append(std::shared_ptr<T> item)
{
vec_.push_back(std::move(item));
}
void printElements()
{
for (int i = 0; i < vec_.size(); i++)
{
// Don't forget to dereference the pointer with `*` in order to
// obtain the _contens of the pointer_ (ie: what it points to),
// rather than the pointer (address) itself
std::cout << *vec_[i] << std::endl;
}
}
};
int main(int argc, char** argv)
{
std::unique_ptr<Container<std::string>> c = std::make_unique<Container<std::string>>();
c->append(std::make_shared<std::string>("hello"));
c->append(std::make_shared<std::string>("world"));
c->printElements();
return 0;
}
आउटपुट:
hello
world
और यहां नया कोड प्रदर्शित करता है कि गैर-कॉन्स्ट वेक्टर को निरंतर सूचक कैसे बनाया जाए। मेरी टिप्पणियाँ यहाँ देखें, और परिवर्तनों का अध्ययन करें:
इसे स्वयं यहां ऑनलाइन चलाएं: https://onlinegdb.com/HyjNx-L5U
2) cpp_template_const_vector_of_smart_ptrs_test_AFTER.cpp
#include <iostream>
#include <memory>
#include <vector>
template <typename T>
class Container
{
private:
// const std::vector<std::shared_ptr<T>> vec_; // does NOT work
// Create an alias to this type just to make the creation below less
// redundant in typing out the long type
using vec_type = std::vector<std::shared_ptr<T>>;
// NON-const object (vector)--so it can be changed
vec_type vec_;
// const pointer to NON-const object--so, vec_p_ can NOT be re-assigned to
// point to a new vector, because it is `const`! But, **what it points to**
// CAN be changed because it is NOT const!
vec_type * const vec_p_ = &vec_;
// This also does NOT work (in place of the line above) because it makes
// the **contents of what you're pointing to const**, which means again
// that the contents of the vector can NOT be modified.
// const vec_type * const vec_p_ = &vec_; // does NOT work
// Here's the compile-time error in gcc when compiling for C++17:
// main.cpp: In instantiation of ‘void Container<T>::append(std::shared_ptr<_Tp>) [with T = std::basic_string<char>]’:
// <span class="error_line" onclick="ide.gotoLine('main.cpp',78)">main.cpp:78:53</span>: required from here
// main.cpp:61:9: error: passing ‘const vec_type {aka const std::vector >, std::allocator > > >}’ as ‘this’ argument discards qualifiers [-fpermissive]
// vec_p_->push_back(std::move(item));
// ^~~~~~
// In file included from /usr/include/c++/7/vector:64:0,
// from main.cpp:22:
// /usr/include/c++/7/bits/stl_vector.h:953:7: note: in call to ‘void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = std::shared_ptr >; _Alloc = std::allocator > >; std::vector<_Tp, _Alloc>::value_type = std::shared_ptr >]’
// push_back(value_type&& __x)
// ^~~~~~~~~
// To prove that vec_p_ can NOT be re-assigned to point to a new vector,
// watch this:
vec_type vec2_;
// vec_p_ = &vec2_; // COMPILE-TIME ERROR! Here is the error:
// main.cpp:44:5: error: ‘vec_p_’ does not name a type; did you mean ‘vec_type’?
// vec_p_ = &vec2_; // COMPILE-TIME ERROR!
// ^~~~~~
// vec_type
// BUT, this works just fine:
vec_type * vec_p2_ = &vec2_; // non-const pointer to non-const data
public:
void append(std::shared_ptr<T> item)
{
vec_p_->push_back(std::move(item));
}
void printElements()
{
for (int i = 0; i < vec_p_->size(); i++)
{
// Notice we have to use a double de-reference here now!
std::cout << *(*vec_p_)[i] << std::endl;
}
}
};
int main(int argc, char** argv)
{
std::unique_ptr<Container<std::string>> c = std::make_unique<Container<std::string>>();
c->append(std::make_shared<std::string>("hello"));
c->append(std::make_shared<std::string>("world"));
c->printElements();
return 0;
}
आउटपुट:
hello
world
संबंधित सवाल
नए सवाल
c++
C ++ एक सामान्य-प्रयोजन प्रोग्रामिंग भाषा है। यह मूल रूप से C के विस्तार के रूप में डिज़ाइन किया गया था और इसमें एक समान सिंटैक्स है, लेकिन यह अब पूरी तरह से अलग भाषा है। C ++ कंपाइलर के साथ संकलित कोड के बारे में प्रश्नों के लिए इस टैग का उपयोग करें। विशिष्ट मानक संशोधन [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] या [C ++ 23], आदि से संबंधित प्रश्नों के लिए संस्करण-विशिष्ट टैग का उपयोग करें। ।