I cannot move a std::vector<std::unique_ptr<..>> from a function:
MSVC complains (C2280) about attempting to reference a deleted function.
How would this work?
#include <vector>
#include <iostream>
#include <memory>
using namespace std;
class foo {
public:
int i;
};
vector<unique_ptr<foo>> test() {
vector<unique_ptr<foo>> ret{};
auto f = make_unique<foo>();
f->i = 1;
ret.push_back(move(f));
return move(ret);
}
int main(int argc, char** argv) {
auto t = test();
for (auto j : t) {
// fails here: --^
cout << j->i << endl;
}
getchar();
}
The complete error message reads:
'std::unique_ptr>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function
It's not the function, it's the loop...
for (auto j : t)
... which attempts to copy-initialize j for each element of t in turn. Recall that a plain auto means value semantics. Use a reference instead:
for (auto const& j : t)
Related
I'm trying to figure out how to use an unordered map to call methods of a class, but when I do it says "expression preceding parenthesis of apparent call must have (pointer-to-) function type". Why is this and what can I do to get it to work?
#include <iostream>
#include <unordered_map>
class Calculator {
public:
void add(int& n) {
++n;
}
void sub(int& n) {
--n;
}
};
int main(int argc, char** args) {
std::unordered_map<char, void(Calculator::*)(int&)> umap;
umap[0] = Calculator::add;
umap[1] = Calculator::sub;
int x;
x = 10;
umap[0](x);
return 0;
}
The code below is giving the error: Call to deleted constructor of 'std::unique_ptr<int>' 'unique_ptr' has been explicitly marked deleted here passing argument to parameter 'item' here.
Could someone please explain why this is? I would have thought everything would be fine because I'm using std::move in the call to foo.add.
#include <iostream>
#include <memory>
#include <set>
class Foo {
public:
void add(std::unique_ptr<int> item) {
set.emplace(std::move(item));
}
private:
std::set<std::unique_ptr<int>> set;
};
int main() {
Foo foo;
std::set<std::unique_ptr<int>> set;
set.emplace(std::make_unique<int>(1));
set.emplace(std::make_unique<int>(2));
set.emplace(std::make_unique<int>(3));
for (auto &item : set) {
foo.add(std::move(item)); // error on this line
}
return 0;
}
Use c++ 17 extract() function.
example
#include <set>
#include <memory>
#include <iostream>
int main() {
auto s = std::set<std::unique_ptr<int>>{};
s.insert(std::make_unique<int>(10));
std::cout << s.size() << "\n";
auto it = s.extract(s.begin());
// Pointer type here just for clarification
std::unique_ptr<int> new_ptr = std::move(it.value());
std::cout << s.size() << "\n";
std::cout << *new_ptr << "\n";
}
Then instead of your for each loop you might use a while loop:
while (!set.empty()) {
auto it = set.extract(set.begin());
foo.add(std::move(it.value());
}
The following code:
#include <cstdio>
#include <iostream>
#include <vector>
template<class type>
struct A {
type i;
A(type j){
i = j;
}
};
template<class type>
std::vector<A<type>*> ve;
int main(int argc, char** args){
ve<int>.push_back(new A<int>(1));
ve<int>.push_back(new A<int>(2));
ve<char>.push_back(new A<char>('a'));
ve<char>.push_back(new A<char>('b'));
for(unsigned int i = 0; i < ve<int>.size(); i++)
std::cout << ve<int>[i]->i << std::endl;
for(unsigned int i = 0; i < ve<char>.size(); i++)
std::cout << ve<char>[i]->i << std::endl;
return 0;
}
outputs:
1
2
a
b
How can I reproduce the same output, but with only one for loop?
Yes I understand the preprocessor made two different vectors here.
Show me how to combine them or show me a generic for loop.
Solution:
#include <cstdio>
#include <iostream>
#include <vector>
struct B {
virtual void memberOut(){}
};
template<class type>
struct A : B{
type i;
A(type j):B(){
i = j;
}
void memberOut(){
std::cout << i << std::endl;
}
};
std::vector<B*> ve;
int main(int argc, char** args){
ve.push_back(new A<int>(1));
ve.push_back(new A<int>(2));
ve.push_back(new A<char>('a'));
ve.push_back(new A<char>('b'));
for(unsigned int i = 0; i < ve.size(); i++)
ve[i]->memberOut();
return 0;
}
Notes:
Either keep it as two containers, or make virtual functions. Both have their uses.
Using a template on a variable just makes two variables.
You can also save another vector of type_index and use typeid to remember what pointer type a void pointer is later on, but that's just a sloppier version of virtual functions. Example:
std::vector<void*> values
std::vector<std::type_index> types
if(types[i]==typeid(A<int>*))
Side Notes:
Try not to get off-base when writing comments.
The objective of comments is to get the question answered, not debate.
I find that Visual Sudio 2012 makes std::mutex copy constructor private, so I think it can only be passed by reference or pointer, and I test both of them, but to my surprise, the pointer style pass, while the reference style rejected by the compiler, and it says:
" error C2248: 'std::mutex::mutex' : cannot access private member declared in class 'std::mutex' ", so the compiler assumes that I try to copy the std::mutex, but in fact I pass it by reference! Anyone have a experience about that? I list my code here:
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
struct SharedMemory
{
public:
int s;
std::mutex mutex;
public:
SharedMemory( int s = 1 ) : s(s){}
void write( int s )
{
mutex.lock();
this->s = s;
mutex.unlock();
}
int read()
{
int tmp;
mutex.lock();
tmp = this->s;
mutex.unlock();
return tmp;
}
void print()
{
std::cout << read() << std::endl;
}
};
void modify( SharedMemory& sm, int i ) // **must use the pointer to the shared memory**
{
//sm->write(i);
sm.write(i);
}
int main( int argc, char* argv[] )
{
SharedMemory sm;
SharedMemory& tmp = sm;
std::vector< std::thread > vec;
for( int i = 0; i < 10; ++i )
{
vec.push_back( std::thread( modify, sm, i ) );
sm.print();
}
for( auto& it : vec ) it.join();
return 0;
}
Below is a simple program in c++0x that makes use of packaged_task and futures. while compiling the program i get error : variable 'std::packaged_task pt1' has initializer but incomplete type
the program is below
#include <future>
#include <iostream>
using namespace std;
int printFn()
{
for(int i = 0; i < 100; i++)
{
cout << "thread " << i << endl;
}
return 1;
}
int main()
{
packaged_task<int> pt1(&printFn);
future<int> fut = pt1.get_future();
thread t(move(pt1));
t.detach();
int value = fut.get();
return 0;
}
The class template packaged_task is undefined for the general case. Only a partial specialization for function type parameters is defined. See the current draft:
template<class> class packaged_task; // undefined
template<class R, class... ArgsTypes>
class packaged_task<R(ArgTypes...)> {
...
void operator()(ArgTypes...);
...
};
Since your printFn function doesn't take any parameters and returns an int you need to use the packaged_task<int()> type.