Creating an auto_ptr with 2 arguments - c++

Hi I have a compile error when I run this code:
std::auto_ptr<MyDisplay> m_display =
std::auto_ptr<MyDisplay>(new MyDisplay(this, m_displayController));
The error is this one:
error C2664: 'MyDisplay::MyDisplay(DemoWindow *,DisplayController*)':
cannot convert parameter 2 from 'std::auto_ptr<_Ty>' to 'DisplayController*'
However when I pass only one argument the code is correct:
std::auto_ptr<DisplayController> m_displayController =
std::auto_ptr<DisplayController>(US_NEW(DisplayController, this));
What is the proper way to create the pointer in the auto_ptr with 2 arguments?

From the error message, it appears that m_displayController is an std::auto_ptr<DisplayController>, while the MyDisplay constructor expects a DisplayController*.
Try :
std::auto_ptr<MyDisplay> m_display =
std::auto_ptr<MyDisplay>(new MyDisplay(this, m_displayController.get()));
or better yet, make the constructor compatible with std::auto_ptr<DisplayController>.
As an aside : the choice of std::auto_ptr here is probably not the best. You might want to read up on the different types of smart pointers, and the different behaviors they have.

I'd like to clarify your idea of creating the auto pointer, which I hope will help.
Your goal here is to create an auto_ptr holding a DisplayController*. You could write
m_displayController = std::auto_ptr<DisplayController>( new DisplayController(x, y) );
Or have a function that returns a pointer, like this :
m_displayController = std::auto_ptr<DisplayController>( US_NEW(x,y) );
You can check out a simple example here.

Related

Was it possible to get a pointer to member from an instance of an object?

I was porting some legacy code to VS 2015 when this compiler error halted the build:
error C3867: 'OptDlg::GetFullModel': non-standard syntax; use '&' to create a pointer to member
Going to the corresponding file and line, I saw this:
Manager mgr = GetDocument()->GetManager();
OptDlg dlg;
...
mgr->SetFullModel(dlg.GetFullModel);
if ( dlg.GetFullModel )
mgr->SetSymm(...
GetFullModeland SetFullModel are the getter/setter pair for a member variable in two different classes:
class Manager {
...
bool GetFullModel() { return m_bFullModel; }
void SetFullModel(bool bFlag) { m_bFullModel = bFlag; }
....
};
class OptDlg {
...
void GetFullModel() { return m_bFullModel; }
void SetFullModel(bool bValue) { m_bFullModel = bValue; if ( bValue ) m_bInside = 0;}
Yep, something's wrong. Was dlg.GetFullModel supposed to be a pointer to a member function? I thought those use the class name, not an instance. Not to mention what that would mean for execution semantics...
C++ is still relatively new to me, so I tried Google. It had a lot on function pointers, but they all looked different from what I had:
&OptDlg::GetFullModel // Standard-compliant
vs
OptDlg::GetFullModel // The "normal" way to mess up getting a pointer to member, it seems
vs
dlg.GetFullModel // ?
Is dlg.GetFullModel just another way of getting a pointer to member function? If not, what is the "standard C++ version", if there is one? Is this just another one of those VS 6 "extensions"?
&OptDlg::GetFullModel // Standard-compliant
If your parameter types were supposed to be taking member functions, that's what you'd use. But they take booleans. It looks like you're just missing parentheses on your function calls, and it should be:
mgr->SetFullModel(dlg.GetFullModel());
if (dlg.GetFullModel())
mgr->SetSymm(...
Probably someone was ignoring warnings (or didn't have them on) and hence a pointer value (being produced through whatever shady means) was always being interpreted as non-NULL, hence boolean true.
Is this just another one of those VS 6 "extensions"?
It would appear to be the case, although this comment is the only documented evidence I can find it was an intentional/advertised "feature". Don't see any formal announcement of it being added or taken out.
It strongly looks to me like someone mis-typed dlg.GetFullModel() (which would call the function), not that they were trying to get a member function pointer.
Presumably the legacy compiler let it slide, taking the address of the function without using & and converting the non-null function pointer to bool (with value true) to pass into the set function.

Method returning std::vector<std::unique_ptr<Object>>

As a continuation of a: Thread, I came across a problem with
writing a method of a class which returns:
std::vector<std::unique_ptr<Object>>
I get compiler errors when such a return type is written. There is some problem with delete operand or something ...
Generally, I've wanted to write a method which initializes vector and returns it.
Could anyone help me how to write it?
EDIT:
I Get:
attempting to reference a deleted function h:\pliki programów (x86)\microsoft visual studio 12.0\vc\include\xmemory0
Here I have the following code snippet. Can I create such a method like this?
std::vector<std::unique_ptr<Object>> Class::TestMethod(int param)
{
std::vector<std::unique_ptr<Object>> array;
auto day = std::make_unique<Object>();
array.push_back(day);
return array;
}
Your error is actually coming from:
array.push_back(day);
This tries to put a copy of day in the vector, which is not permitted since it is unique.
Instead you could write array.push_back( std::move(day) ); however the following would be better, replacing auto day...:
array.emplace_back();
The copy constructor of std::unique_ptr is deleted. That causes a problem in the line:
array.push_back(day);
Use
array.push_back(std::move(day));

c++ attempting to reference deleted function

I have been playing around with std::unique_ptr and the std::for_each algorithm to learn them and I then received this error "attempting to reference a deleted function" when I am attempting to move some variables from one container (std::map) to another.
This code is currently executed in a member function. Foo is just a generic class.
std::for_each(m_list1.begin(), m_list1.end(),
[&](std::pair<std::size_t,std::unique_ptr<Foo>> data_pair)
{
m_list2[data_pair.first] = std::unique_ptr<Foo>(std::move(data_pair.second));
});
m_list1.clear();
I tried various things but the problems still persists. I then tried using range-based for instead and suddenly it works.
for (auto& data_pair : m_list1)
{
m_list2[data_pair.first] = std::unique_ptr<Foo>(std::move(data_pair.second));
}
m_list1.clear();
What I want to know is why the second code executed with no problem, while the first code produced the error.
If you need more specific information, Just ask. If there's bad practice in my coding style, please advice on how to make it better.
There are two errors in your for_each code. First, map::value_type is pair<const Key, Value>. Second, your lambda expression is taking the argument by value, which means it attempts to copy the unique_ptr, hence the error. To fix it, take the argument by reference.
[&](std::pair<const std::size_t, std::unique_ptr<Foo>>& data_pair)
// ^^^^^ ^^^
{
m_list2[data_pair.first] = std::unique_ptr<Foo>(std::move(data_pair.second));
}
A better option is to not mention those types explicitly, instead use decltype
[&](decltype(m_list1)::value_type& data_pair)
{
m_list2[data_pair.first] = std::unique_ptr<Foo>(std::move(data_pair.second));
}
Now, your range-based for worked because you were binding the elements of the map to a reference by using for(auto& data_pair : m_list1). You'd have run into the same error as before if you'd instead used for(auto data_pair : m_list1) because that'd have attempted to make a copy of the elements.

QT Cannot convert 'std::string' to 'std::string*' in initialization

I got some problems in creating my program for mobile using QT C++
When i run it i get this: cannot convert 'std::string' to 'std::string*' in initialization
And theres code for that error:
void rozvrh_b17::pars(string par)
{
data = new std::string*(par);
printf(data->data());
}
//data and par are std::string
//without that new std::string*() it does similiar error
And i ask how to convert std::string to std::string* ??
EDIT:
i made this function to transfer data from one form to another and i need to remember that parameter...
I downvoted you because this question shows no research effort.
string * data = &par;
std::string* is a pointer type. You have a std::string, and it's address is the pointer type you want. This is one of the first principles of using pointers.
What do you really try to do?
If you just want to print the string then this should work:
void rozvrh_b17::pars(string par)
{
printf(par.c_str());
}
If you want to create a copy of string on the heap then you need this:
std::string* data = new std::string(par);
but that doesn't make much sense.
You are trying to assign a string from a pointer to string. In this particular case I see several things.
You don't need a copy at all - simply use par right away
You better make par a const ref: void rozvrh_b17::pars(const string& par)
You should use only string whaen calling new otherwise you create a pointer to string. So do: data = new std::string(par);

Boost FOR_EACH Over A Ptr_Vector?

I'm currently having fun trying to learn some of the Boost libary. I'm currently doing what I guess will be a future homework project (semester hasn't started yet). However, this question is not about the homework problem, but about Boost.
Code:
/* AuctionApplication.h */
class AuctionApplication : boost::noncopyable
{
private:
boost::ptr_vector<Auction> auctions_;
boost::ptr_vector<Bidder> bidders_;
boost::ptr_vector<Bid> bids_;
/* AuctionApplication.cpp */
Bid *AuctionApplication::GetLatestBid(const Auction *auction)
{
Bid *highestBid = 0;
BOOST_FOREACH(Bid *bid, bids_) // Error here!
if (bid->GetAuction()->GetName() == auction->GetName())
highestBid = bid;
BOOST_FOREACH use to work with normal vectors with the exact same code as above. Since I've started using ptr_vectors I get the error:
error C2440: '=' : cannot convert from 'Bid' to 'Bid *'
Leading me to believe that ptr_vector somehow obscures the pointer from the foreach method.
If I instead write
BOOST_FOREACH(Bid *bid, bids_)
I get four errors of the type
error C2819: type 'Bid' does not have an overloaded member 'operator ->'
which sucks, because I know bid is a pointer.
How can I make BOOST_FOREACH iterate properly over the ptr_vectors?
ptr_vector takes ownership of heap allocated objects and presents each object as a reference so you don't need dereferencing and you use . instead of -> to access member variables/functions. e.g.
Bid highestBid = 0;
BOOST_FOREACH (Bid& bid, bids_)
if (bid.GetAuction()->GetName() == auction->GetName())
highestBid = &bid;