I keep getting this error when compiling, but I don't know why. I have looked at this post and this one, but they appeared to be different problems.
The relavent code structure is:
// main.cpp
#include "MyClass.h"
int main() {
MyClass newClass = MyClass();
}
// MyClass.h
#include <string>
#include <sstream>
#include <vector>
using namespace std;
class Node;
class MyClass {
private:
vector<Node*> nodes;
int number;
stringstream fileInfo;
public:
MyClass();
~MyClass();
};
// MyClass.cpp
#include "MyClass.h"
MyClass::MyClass() {
number = 1;
}
MyClass::~MyClass() {}
The error I get when compiling is:
main.cpp: In function 'int main()':
main.cpp:4:29: error: use of deleted function 'MyClass(const MyClass&)'
MyClass new Class = MyClass();
^
In file included from main.cpp:1:0:
MyClass.h:7:7: note: 'MyClass::MyClass(const MyClass&)' is implicitly deleted because the definition would be ill-formed:
class MyClass {
^
MyClass.h:7:7: error: use of deleted function 'std::__cxx11::basic_stringstream<_CharT, _Traits, _Alloc>::basic_stringstream(const std::__cxx11:basic_stringstream<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]'
In file included from MyClass.h:2:0,
from main.cpp:1:
/usr/included/c++/5/sstream:721:7: note: declared here
basic_stringstream(const basic_stringstream&) = delete;
^
I have tried initializing all the class members in the constructor, but that didn't change the error. Other than that I can't think of what is wrong.
The problem is that your class is not copy-able because it contains a std::stringstream (which is itself not copy-able). This results in its copy constructor being deleted, which is what the compiler is trying to tell you. To fix this, simply don't use the copy-initialization syntax in your main function.
int main() {
MyClass newClass;
}
Related
I'm currently working on a project in C++ in which I have a list of structs stored in a vector that have a lot processing associated with them. In order to speed things up, I've chosen to split the program across multiple threads, and the lazy way I've chosen to do this is by adding a mutex to each struct in the standard library vector. This way I can have a number of threads iterate over the array and basically take ownership of the individual elements by calling mutex.try_lock(), and either completing the associated processing with that element, or moving onto the next open one.
Before we get started, note that the following actually does work.
#include <mutex>
#include <vector>
struct foo {
int a;
std::mutex b;
};
void working_demo () {
// assign by initializer list
foo f = {.a = 1};
}
int main () {
working_demo();
}
So, I intend to populate my standard vector in a way very similar to above, and it doesn't work.
#include <mutex>
#include <vector>
struct foo {
int a;
std::mutex b;
};
void broken_demo () {
std::vector<foo> bar;
// assign by initializer list
bar.push_back({.a = 1});
}
int main () {
broken_demo();
}
Compiler Error:
clang++ -std=c++11 -Wall -Wextra -Wfatal-errors -pedantic -I./ -c -o demo.o demo.cpp
demo.cpp:13:20: warning: designated initializers are a C99 feature [-Wc99-extensions]
bar.push_back({.a = 1});
^~~~~~
In file included from demo.cpp:1:
In file included from /usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/mutex:38:
In file included from /usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/tuple:39:
In file included from /usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/array:39:
In file included from /usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/stdexcept:39:
In file included from /usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/string:41:
In file included from /usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/allocator.h:46:
In file included from /usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/x86_64-pc-linux-gnu/bits/c++allocator.h:33:
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/ext/new_allocator.h:146:8: fatal error: call to implicitly-deleted copy constructor of 'foo'
_Up(std::forward<_Args>(__args)...)))
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/alloc_traits.h:483:24: note: in instantiation of exception specification for
'construct<foo, foo>' requested here
noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/vector.tcc:115:21: note: in instantiation of exception specification for 'construct<foo, foo>'
requested here
_Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/stl_vector.h:1201:9: note: in instantiation of function template specialization
'std::vector<foo, std::allocator<foo> >::emplace_back<foo>' requested here
{ emplace_back(std::move(__x)); }
^
demo.cpp:13:9: note: in instantiation of member function 'std::vector<foo, std::allocator<foo> >::push_back' requested here
bar.push_back({.a = 1});
^
demo.cpp:6:16: note: copy constructor of 'foo' is implicitly deleted because field 'b' has a deleted copy constructor
std::mutex b;
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/std_mutex.h:94:5: note: 'mutex' has been explicitly marked deleted here
mutex(const mutex&) = delete;
^
I'm fairly certain that this is saying the reason this won't work is that the structure is attempting to call the copy constructor for the mutex, which in fact does not have a copy constructor. I explicitly don't want to do be doing this.
My initial thought is that in order to make sure it doesn't even try to call the copy constructor for the mutex, I can create my own constructor for my class and basically explicitly leave out the copying for the mutex. This method would look like this - but it also doesn't work.
#include <mutex>
#include <vector>
struct foo {
foo (int A): a(A) {;}
int a;
std::mutex b;
};
void broken_demo () {
std::vector<foo> bar;
// assign by initializer list
bar.emplace_back(1);
}
int main () {
broken_demo();
}
Compiler Error:
clang++ -std=c++11 -Wall -Wextra -Wfatal-errors -pedantic -I./ -c -o demo.o demo.cpp
In file included from demo.cpp:2:
In file included from /usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/vector:65:
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/stl_construct.h:75:38: fatal error: call to implicitly-deleted copy constructor of 'foo'
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/stl_uninitialized.h:83:8: note: in instantiation of function template specialization
'std::_Construct<foo, foo>' requested here
std::_Construct(std::__addressof(*__cur), *__first);
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/stl_uninitialized.h:134:2: note: in instantiation of function template specialization
'std::__uninitialized_copy<false>::__uninit_copy<std::move_iterator<foo *>, foo *>' requested here
__uninit_copy(__first, __last, __result);
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/stl_uninitialized.h:289:19: note: in instantiation of function template specialization
'std::uninitialized_copy<std::move_iterator<foo *>, foo *>' requested here
{ return std::uninitialized_copy(__first, __last, __result); }
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/stl_uninitialized.h:310:19: note: in instantiation of function template specialization
'std::__uninitialized_copy_a<std::move_iterator<foo *>, foo *, foo>' requested here
return std::__uninitialized_copy_a
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/vector.tcc:473:10: note: in instantiation of function template specialization
'std::__uninitialized_move_if_noexcept_a<foo *, foo *, std::allocator<foo> >' requested here
= std::__uninitialized_move_if_noexcept_a
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/vector.tcc:121:4: note: in instantiation of function template specialization 'std::vector<foo,
std::allocator<foo> >::_M_realloc_insert<int>' requested here
_M_realloc_insert(end(), std::forward<_Args>(__args)...);
^
demo.cpp:15:9: note: in instantiation of function template specialization 'std::vector<foo, std::allocator<foo> >::emplace_back<int>' requested here
bar.emplace_back(1);
^
demo.cpp:8:16: note: copy constructor of 'foo' is implicitly deleted because field 'b' has a deleted copy constructor
std::mutex b;
^
/usr/sup/bin/../lib/gcc/x86_64-pc-linux-gnu/9.1.0/../../../../include/c++/9.1.0/bits/std_mutex.h:94:5: note: 'mutex' has been explicitly marked deleted here
mutex(const mutex&) = delete;
^
1 error generated.
Any thoughts on a solution to this? I'm hoping to keep the code relatively simple, but I'm uncertain how to make the standard vector behave, or at least use it properly.
The problem is that in your code instances of foo are passed by value. So when you put something into the vector, a copy needs to be created. A simple way to avoid that would be to put pointers to foo into the vector. You can wrap the pointers into some reference-counting mechanism so that you don't have to keep track of freeing the objects.
Here is a short example using std::unique_ptr that will auto-delete all foo instances in the vector when the vector goes out of scope:
#include <mutex>
#include <vector>
#include <memory>
#include <iostream>
#include <functional>
struct foo {
foo(int A) : a(A) {}
int a;
std::mutex b;
};
void fixed_demo () {
std::vector<std::unique_ptr<foo>> bar;
std::unique_ptr<foo> p(new foo(1));
bar.push_back(std::move(p));
bar.emplace_back(new foo(2));
for (auto it = bar.begin(); it != bar.end(); ++it) {
(*it)->b.lock();
std::cout << (*it)->a << std::endl;
(*it)->b.unlock();
}
}
int main () {
fixed_demo();
return 0;
}
After looking at one of the solutions, I think actually this solution fits best what I was going for. I wouldn't have been able to figure this out without the helpful advice above.
#include <mutex>
#include <vector>
struct foo {
int a;
std::mutex b;
foo (int a) : a(a) {;}
foo (const foo &f) : a(f.a) {;}
};
void other_fixed_demo ()
{
std::vector<foo> bar;
bar.emplace_back(1);
}
int main () {
other_fixed_demo();
}
I couldn't say why, but apparently two things are happening here. First, we are calling the constructor with the 1 input, and then somewhere within emplace_back() we're calling the copy constructor. Both need to explicitly not include the mutex in each way of creating the struct, and the above solution avoids that.
#include <map>
#include <memory>
#include <iostream>
using namespace std;
class test
{
public:
test(){}
~test(){}
enum type
{
error = 0
};
private:
shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>();//build error
//shared_ptr<map<type, int>> member_ = make_shared<map<type, int>>();//build ok
};
int main()
{
return 0;
}
when i compile program with "shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>()"
main.cpp:17:63: error: expected ‘;’ at end of member declaration
shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>();
^
main.cpp:17:67: error: expected unqualified-id before ‘>>’ token
shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>();
^
main.cpp:17:58: error: wrong number of template arguments (1, should be at least 2)
shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>();
^
In file included from /usr/include/c++/5/map:61:0,
from main.cpp:1:
/usr/include/c++/5/bits/stl_map.h:96:11: note: provided for ‘template<class _Key, class _Tp, class _Compare, class _Alloc> class std::map’
class map
^
main.cpp:17:42: error: parse error in template argument list
shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>();
^
main.cpp:17:42: error: cannot resolve overloaded function ‘make_shared’ based on conversion to type ‘std::shared_ptr<std::map<int, test::type> >’
Have tried your code with Online C++ Compiler, got the same errors with C++, C++11, and C++14 compatible compilers, but got compiled well with C++17 compatible compiler. This means that your code is not legal in C++ standards prior to C++17. As pointed out by others, the code, however, compiled well on other online compiler sites even with C++11 and C++14 standards. So I would guess the errors are due to supported / unsupported features of compilers.
Well, you are not supposed to initialize class members like this anyway. The initialization of class members should happen in the class constructor, like so:
#include <map>
#include <memory>
#include <iostream>
using namespace std;
class test
{
public:
test() { member_ = make_shared<map<int, type>>(); }
~test() { }
enum type
{
error = 0
};
private:
shared_ptr<map<int, type>> member_;
};
int main()
{
return 0;
}
This compiles fine even in Online C++ Compiler which is the only place we are managing to reproduce the problem.
How to add object of class to vector in another class.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class info{
private:
int id;
string name;
public:
info(int extId, string extName) {
this->id = extId;
this->name = extName;
}
};
class db {
private:
vector<info> infoVector;
public:
void pushData(info * data) {
this->infoVector.push_back(&data);
}
};
int main(){
info * testData = new info(123, "nice");
db database;
database.pushData(testData);
return 0;
}
I am creating a object of info class. The object contains one int and one string variables. Then I am creating db object and I am passing there a testData object.
I got error message while building project.
main.cpp: In member function ‘void db::pushData(info*)’:
main.cpp:23:44: error: no matching function for call to ‘std::vector<info>::push_back(info*&)’
this->infoVector.push_back(data);
^
In file included from /usr/include/c++/5/vector:64:0,
from main.cpp:2:
/usr/include/c++/5/bits/stl_vector.h:913:7: note: candidate: void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = info; _Alloc = std::allocator<info>; std::vector<_Tp, _Alloc>::value_type = info]
push_back(const value_type& __x)
^
/usr/include/c++/5/bits/stl_vector.h:913:7: note: no known conversion for argument 1 from ‘info*’ to ‘const value_type& {aka const info&}’
What am I doing wrong?
It looks like you are trying to pass the address of an info * type to vector<info>::push_back, which only accepts types of const info & or info &&. Try using the dereference operator * instead of the address-of operator & when you call push_back:
this->infoVector.push_back(*data);
This isn't a great way to use pointers, however, and could lead to memory leakage or segfaults if data is removed from the vector or if it is deleted. It is better for the vector to own its members, so you might consider doing this instead:
class db {
private:
vector<info> infoVector;
public:
void pushData(info data) { // note: not a pointer
this->infoVector.push_back(data); // note: not address-of
}
};
int main(){
info testData(123, "nice"); // note: not a pointer
db database;
database.pushData(testData);
return 0;
}
Otherwise, if you really want infoVector to contain pointers, declare it as:
std::vector<info*> infoVector;
Then remove the address-to operator.
P.S., avoid using namespace std whenever possible!
You have vector<info> and you want to put info *, try to do:
int main(){
info testData(123, "nice");
db database;
database.pushData(testData);
return 0;
}
I have a Load-Method which builds my unique_ptr (will be more than one later on) and a method to add these unique_ptr to my unordered map. But the code does not compile and I guess it has something to do with scoping...
Here is the code:
#include <unordered_map>
#include <memory>
class MyClass
{
public:
std::string Name;
};
using Map = std::unordered_map<std::string,std::unique_ptr<MyClass>>;
class MyContainer
{
private:
Map myMap;
void AddItem(std::unique_ptr<MyClass> item)
{
myMap.emplace("test", item);
}
public:
void LoadItems()
{
//Read a file ... do something before etc..
std::unique_ptr<MyClass> someItem(new MyClass);
someItem->Name = "FooBar";
AddItem(someItem);
}
};
This is one of the g++ error messages:
error: use of deleted function 'std::unique_ptr<_Tp,
_Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = MyClass; _Dp = std::default_delete]'
What is the best way to get this working? I tried changing the signature of the AddItem-method like so:
void AddItem(std::unique_ptr<MyClass>& item) //takes a reference now...
This leads to a real cryptic error message:
In instantiation of 'constexpr std::pair<_T1, _T2>::pair(_U1&&, const
_T2&) [with _U1 = const char (&)[5]; = void; _T1 = const std::basic_string; _T2 = std::unique_ptr]': e:\devtools\winbuilds\include\c++\4.8.3\bits\hashtable_policy.h:177:55:
required from 'std::__detail::_ ...
I suggest trying this piece of code on the fly here, to see the error messages:
http://cpp.sh/
You cannot copy a unique_ptr, because then it will not be unique. You have to move it - AddItem(std::move(someItem)); and myMap.emplace("test", std::move(item));.
You are trying to copy unique_ptr which is not allowed (that constructor is deleted as gcc says in the error). Instead of that you can try with std::move:
#include <unordered_map>
#include <memory>
#include <utility>
class MyClass
{
public:
std::string Name;
};
using Map = std::unordered_map<std::string,std::unique_ptr<MyClass>>;
class MyContainer
{
private:
Map myMap;
void AddItem(std::unique_ptr<MyClass> item)
{
myMap.emplace("test", std::move(item));
}
public:
void LoadItems()
{
//Read a file ... do something before etc..
std::unique_ptr<MyClass> someItem(new MyClass);
someItem->Name = "FooBar";
AddItem(std::move(someItem));
}
};
Be aware, do not use the moved object afterwards.
You can consider to use shared_ptr instead.
abstract base class:
#ifndef BUILDINGORG_H
#define BUILDINGORG_H
#include <iostream>
#include <memory>
#include <vector>
class BuildingOrg
{
public:
BuildingOrg(int _id);
virtual int addBuildingComponent(std::shared_ptr<BuildingOrg> buildingOrg,
std::string _type) const;
virtual void removeBuildingComponent(std::shared_ptr<BuildingOrg> buildingOrg);
virtual void getInfo()=0;
private:
int id;
std::string type;
};
#endif // BUILDINGORG_H
concrete subclass:
#ifndef BUILDINGCOMPONENT_H
#define BUILDINGCOMPONENT_H
#include "buildingorg.h"
class BuildingComponent : public BuildingOrg
{
public:
BuildingComponent(int _id);
int addBuildingComponent(std::shared_ptr<BuildingOrg> _buildingOrg,
std::string _type) const override;
void removeBuildingComponent(std::shared_ptr<BuildingOrg> buildingOrg)
override;
void getInfo() override;
private:
std::vector<std::shared_ptr<BuildingOrg>> building_Org;
};
#endif // BUILDINGCOMPONENT_H
Implementation of subclass:
#include "buildingcomponent.h"
BuildingComponent::BuildingComponent(int _id):
BuildingOrg(_id)
{
}
int BuildingComponent::addBuildingComponent(std::shared_ptr<BuildingOrg> _buildingOrg, std::string _type) const
{
building_Org.push_back(_buildingOrg);// I am having error here
return 1;
}
void BuildingComponent::removeBuildingComponent(std::shared_ptr<BuildingOrg> buildingOrg)
{
}
void BuildingComponent::getInfo()
{
}
When I try to put shared pointer in my Vector I get this nasty error;
I really don't know why I am getting the error:
cpp:10: error: passing 'const std::vector<std::shared_ptr<BuildingOrg> >' as 'this' argument of 'void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::shared_ptr<BuildingOrg>; _Alloc = std::allocator<std::shared_ptr<BuildingOrg> >; std::vector<_Tp, _Alloc>::value_type = std::shared_ptr<BuildingOrg>]' discards qualifiers [-fpermissive]
building_Org.push_back(_buildingOrg);
I don’t understand what is it saying.
The const in int addBuildingComponent(std::shared_ptr<BuildingOrg> _buildingOrg, std::string _type) const override; is a promise that addBuildingComponent will not change BuildingComponent. However, it tries to modify the member variable building_Org with the push_back()...
Removing the const from addBuildingComponent() should fix the error.
The discards qualifiers part of the error message refers to the conflict with the const qualifier of the member function.
C++ template related error messages can be notoriously difficult to parse at first, but it does get easier with practice :-)
You defined BuildingComponent::addBuildingComponent method as const (i.e. that it won't change member varialbles), but you are adding passed in value to a member list (i.e. changing the member variable).
addBuildingComponent() is a const method. within its scope, *this is const, and so this->building_Org is const.
std::vector::push_back() is a non-const method. So it can't be called in a context where the vector is const.