I got the following error:
Database.hpp: In member function ‘Table<T, S>& Table<T, S>::operator=(const Table<T, S>&) [with T = int, int S = 3, Table<T, S> = Table<int, 3>]’:
Database.hpp:40:8: instantiated from ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, const _Tp&) [with _Tp = List, _Alloc = std::allocator<List>, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<List*, std::vector<List> >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = List*]’
/usr/include/c++/4.6/bits/stl_vector.h:834:4: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = List, _Alloc = std::allocator<List>, std::vector<_Tp, _Alloc>::value_type = List]’
SelectiveReading.hpp:139:34: instantiated from here
Database.hpp:34:16: error: invalid initialization of non-const reference of type ‘Table<int, 3>&’ from an rvalue of type ‘Table<int, 3>* const’
I have the following ADTs. I don't get it what is wrong with them.
// this is Database.hpp
template <class T, int S>
class Table
{
T tab[S];
public:
inline T& operator[](int i)
{
return tab[i];
}
inline const T& operator[](int i) const
{
return tab[i];
}
Table() {}
~Table() {}
Table(const Table &t)
{
for ( int i=0; i<S; ++i )
{
tab[i] = t[i];
}
}
Table& operator=(const Table &t)
{
for ( int i=0; i<S; ++i )
{
tab[i] = t[i];
}
return this;
}
};
typedef Table<int,3> Date;
struct List
{
Date AnnouncementDate;
int BonusShares;
int StockSplit;
int CashDividend;
bool DividendPayment;
Date ExDividendDate;
Date ShareRecordDate;
Date BonusSharesListingDate;
};
typedef std::vector<List> Database;
While the call was like:
List record;
// (...)
Data.push_back(record); // this is SelectiveReading.hpp:139:34
In the last line of your operator=, you are returning this (a pointer), when you mean to return *this (a reference).
return this; needs to be return *this;
Related
What's wrong with the operator() inside Entity (hasher) ?
Copy-pasting it to a separate struct works :
#include <bitset>
#include <unordered_map>
using namespace std;
struct Entity {
string name;
size_t operator()(const Entity& k) const noexcept
{ return std::hash<string>{}(k.name); }
bool operator== (const Entity& e) const noexcept
{ return e.name == name; }
};
struct KeyHasher {
size_t operator()(const Entity& k) const noexcept
{ return std::hash<string>{}(k.name); }
};
int main(){
// unordered_map<const Entity, bitset<24>, KeyHasher> m1; // OK
unordered_map<const Entity, bitset<24>> m2; // unordered_map() ill-formed ?
return 0;
}
Error :
<source>: In function 'int main()':
<source>:25:43: error: use of deleted function 'std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map()
[with _Key = const Entity; _Tp = std::bitset<24>; _Hash = std::hash<const Entity>; _Pred = std::equal_to<const Entity>; _Alloc = std::allocator<std::pair<const Entity, std::bitset<24> > >]'
25 | unordered_map<const Entity, bitset<24>> m2;
| ^~
In file included from /opt/compiler-explorer/gcc-cxx-modules-trunk-20220427/include/c++/11.0.0/unordered_map:47,
from <source>:3:
/opt/compiler-explorer/gcc-cxx-modules-trunk-20220427/include/c++/11.0.0/bits/unordered_map.h:141:7: note: 'std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map() [with _Key = const Entity; _Tp = std::bitset<24>; _Hash = std::hash<const Entity>; _Pred = std::equal_to<const Entity>; _Alloc = std::allocator<std::pair<const Entity, std::bitset<24> > >]'
is implicitly deleted because the default definition would be ill-formed:
141 | unordered_map() = default;
run
If you don't specify a hash function for your map it defaults to std::hash<Key> with your key type.
So you will need to define this specialization of std::hash
template<>
struct std::hash<const Entity>
{
std::size_t operator()(const Entity const& k) const noexcept
{
return std::hash<string>{}(k.name);
}
}
I have a class that contains a vector of vector. It is allocator aware. When trying to call the operator[] to store elements in a reference, Visual Studio 2015 fails to compile, AppleClang (latest) is fine with it.
I am unsure whether this is a bug or not, which compiler is right, or if there is some undefined behaviour somewhere in my code.
Here is a concise example, with everything as simple as possible.
#include <cstdlib>
#include <memory>
#include <new>
#include <vector>
/* Allocator */
template <class T>
struct my_allocator {
typedef T value_type;
my_allocator() = default;
template <class U>
constexpr my_allocator(const my_allocator<U>&) noexcept {
}
T* allocate(std::size_t n) {
if (n > std::size_t(-1) / sizeof(T))
throw std::bad_alloc();
if (auto p = static_cast<T*>(std::malloc(n * sizeof(T))))
return p;
throw std::bad_alloc();
}
void deallocate(T* p, std::size_t) noexcept {
std::free(p);
}
};
template <class T, class U>
bool operator==(const my_allocator<T>&, const my_allocator<U>&) {
return true;
}
template <class T, class U>
bool operator!=(const my_allocator<T>&, const my_allocator<U>&) {
return false;
}
/* Example Element */
struct X {
X() = default;
X(X&&) = default;
X& operator=(X&&) = default;
X(const X&) = delete;
X& operator=(const X&) = delete;
int test = 42;
};
/* Example Container Class */
template <class T, class Allocator = std::allocator<T>>
struct vec_of_vec {
using OuterAlloc = typename std::allocator_traits<
Allocator>::template rebind_alloc<std::vector<T, Allocator>>;
vec_of_vec(const Allocator& alloc = Allocator{})
: data(10, std::vector<T, Allocator>{ alloc },
OuterAlloc{ alloc }) {
for (int i = 0; i < 10; ++i) {
data[i].resize(42);
}
}
std::vector<T, Allocator>& operator[](size_t i) {
return data[i];
}
std::vector<std::vector<T, Allocator>, OuterAlloc> data;
};
/* Trigger Error */
int main(int, char**) {
my_allocator<X> alloc;
vec_of_vec<X, my_allocator<X>> test(alloc);
X& ref_test = test[0][0]; // <-- Error Here!
printf("%d\n", ref_test.test);
return 0;
}
VS tries to use the copy constructor of X.
error C2280: 'X::X(const X &)': attempting to reference a deleted function
function main.cpp(42): note: see declaration of 'X::X'
Is there something I am missing with the use of allocators and allocator_traits?
GCC error sheds light on what's going on, potentially same in VS2015 case.
In file included from memory:65,
from prog.cc:2:
bits/stl_uninitialized.h: In instantiation of '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = __gnu_cxx::__normal_iterator<const X*, std::vector<X, my_allocator<X> > >; _ForwardIterator = X*; _Allocator = my_allocator<X>]':
bits/stl_vector.h:454:31: required from 'std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = X; _Alloc = my_allocator<X>]'
bits/alloc_traits.h:250:4: required from 'static std::_Require<std::__and_<std::__not_<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type>, std::is_constructible<_Tp, _Args ...> > > std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::vector<X, my_allocator<X> >; _Args = {const std::vector<X, my_allocator<X> >&}; _Alloc = my_allocator<std::vector<X, my_allocator<X> > >; std::_Require<std::__and_<std::__not_<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type>, std::is_constructible<_Tp, _Args ...> > > = void]'
bits/alloc_traits.h:344:16: required from 'static decltype (std::allocator_traits<_Alloc>::_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) std::allocator_traits<_Alloc>::construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::vector<X, my_allocator<X> >; _Args = {const std::vector<X, my_allocator<X> >&}; _Alloc = my_allocator<std::vector<X, my_allocator<X> > >; decltype (std::allocator_traits<_Alloc>::_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) = void]'
bits/stl_uninitialized.h:351:25: required from '_ForwardIterator std::__uninitialized_fill_n_a(_ForwardIterator, _Size, const _Tp&, _Allocator&) [with _ForwardIterator = std::vector<X, my_allocator<X> >*; _Size = long unsigned int; _Tp = std::vector<X, my_allocator<X> >; _Allocator = my_allocator<std::vector<X, my_allocator<X> > >]'
bits/stl_vector.h:1466:33: required from 'void std::vector<_Tp, _Alloc>::_M_fill_initialize(std::vector<_Tp, _Alloc>::size_type, const value_type&) [with _Tp = std::vector<X, my_allocator<X> >; _Alloc = my_allocator<std::vector<X, my_allocator<X> > >; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = std::vector<X, my_allocator<X> >]'
bits/stl_vector.h:421:9: required from 'std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const value_type&, const allocator_type&) [with _Tp = std::vector<X, my_allocator<X> >; _Alloc = my_allocator<std::vector<X, my_allocator<X> > >; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = std::vector<X, my_allocator<X> >; std::vector<_Tp, _Alloc>::allocator_type = my_allocator<std::vector<X, my_allocator<X> > >]'
prog.cc:59:42: required from 'vec_of_vec<T, Allocator>::vec_of_vec(const Allocator&) [with T = X; Allocator = my_allocator<X>]'
prog.cc:76:46: required from here
bits/stl_uninitialized.h:275:25: error: no matching function for call to '__gnu_cxx::__alloc_traits<my_allocator<X>, X>::construct(my_allocator<X>&, X*, const X&)'
__traits::construct(__alloc, std::__addressof(*__cur), *__first);```
Wandbox
if we go from bottom to top we see:
vec_of_vec constructor
filling vector<vector> by 10 copies of empty inner vector
construction of copies
Despite of the fact that inner vector is empty, its copy constructor requires that the type it contains is copy-constructible.
P.S.
I don't know how clang overcomes this. Potentially it recognises that vector<vector> if filled with default value (if constructor with passed allocator instance still qualifies as default) and so instead of copying uses default construction
EDIT:
To fix the error replace
vec_of_vec(const Allocator& alloc = Allocator{})
: data(10, std::vector<T, Allocator>{ alloc },
OuterAlloc{ alloc }) {
for (int i = 0; i < 10; ++i) {
data[i].resize(42);
}
}
by
vec_of_vec(const Allocator& alloc = Allocator{})
{
data.resize(10); // here we don't `fill` it by copies but default-construct 10 instances
for (int i = 0; i < 10; ++i) {
data[i].resize(42);
}
}
or version for stateful allocator:
vec_of_vec(const Allocator& alloc = Allocator{}):
data(OuterAlloc(alloc))
{
for (int i = 0; i < 10; ++i) {
data.emplace_back(alloc);
data.back().resize(42);
}
}
I'm beginer in templates and cann't resolve one compiler issue. The problem is in the following:
I have two classes.
class TMessage
{
public:
int Priority;
TMessageType Type;
bool operator> (const TMessage& m)
{
return m.Priority > Priority;
}
bool operator< (const TMessage& m)
{
return m.Priority < Priority;
}
};
template<typename T> class TMessageQueue
{
public:
T* Buffer;
int QueueStartOffset;
void SortMessages(int putPointer)
{
std::sort(Buffer+QueueStartOffset,Buffer+ putPointer);
}
};
In file included from /usr/include/c++/4.8/algorithm:62:0,
from TMessageQueue.h:2,
from TWriterThread.h:2,
from TWriterThread.cpp:1:
/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of ‘_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, const _Tp&) [with _RandomAccessIterator = TMessage*; _Tp = TMessage]’:
/usr/include/c++/4.8/bits/stl_algo.h:2283:70: required from ‘_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = TMessage*]’
/usr/include/c++/4.8/bits/stl_algo.h:2315:54: required from ‘void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = TMessage*; _Size = long int]’
/usr/include/c++/4.8/bits/stl_algo.h:5461:36: required from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = TMessage*]’
TMessageQueue.h:158:60: required from ‘void TMessageQueue::SortMessages(int) [with T = TMessage]’
TMessageQueue.h:143:26: required from ‘TRetCode TMessageQueue::Put(T&) [with T = TMessage]’
TWriterThread.cpp:59:34: required from here
/usr/include/c++/4.8/bits/stl_algo.h:2245:19: error: passing ‘const TMessage’ as ‘this’ argument of ‘bool TMessage::operator<(const TMessage&)’ discards qualifiers [-fpermissive]
while (__pivot < *__last)
^
make: *** [all] Error 1
What is the problem? Used compiler g++.
The operator< and operator> methods need to be const
bool operator> (const TMessage& m) const { ... }
bool operator< (const TMessage& m) const { ... }
In addition the first answer by simpel01,
this bad code:
bool operator> (const TMessage& m)
{
return m.Priority > Priority;
}
bool operator< (const TMessage& m)
{
return m.Priority < Priority;
}
In operator > must return this->Priority > m.Priority not m.Priority > this->Priority because operator > activated by object this and actually you want to say if I'm (object this) big than from m.
what you do is reverse!
and fix operator < to this->Priority < m.Priority
Using the below code, i get the following compile error:
In static member function ‘static std::string ctedata::Record::getDispatcher<std::basic_string<char> >::impl(const ctedata::Record&, const string&)’:
/home/jason/CrownTheEmpire/lib/ctedata/data.h:111:38: error: passing ‘const std::map<std::basic_string<char>, std::basic_string<char> >’ as ‘this’ argument discards qualifiers [-fpermissive]
return rec.fieldValues_[field];
^
In file included from /usr/include/c++/5.1.0/map:61:0,
from /usr/include/cppconn/connection.h:30,
from /usr/include/cppconn/driver.h:30,
from /home/jason/CrownTheEmpire/lib/ctedata/data.h:6,
from /home/jason/CrownTheEmpire/lib/ctedata/data.cc:3:
/usr/include/c++/5.1.0/bits/stl_map.h:471:7: note: in call to ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::basic_string<char>; _Tp = std::basic_string<char>; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, std::basic_string<char> > >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = std::basic_string<char>; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::basic_string<char>]’
operator[](const key_type& __k)
^
class Record
{
public:
Record() {
isNew_ = true;
}
Record(sql::ResultSet *resultSet) : resultSet_(resultSet) {
isNew_ = false;
}
void loadData();
virtual void init() = 0;
bool isNew() { return isNew_; }
void setValue(const std::string& field, const std::string& value);
template<typename T>
T getValue(const std::string& field) const {
return Record::getDispatcher<T>::impl(*this, field);
}
protected:
sql::ResultSet* resultSet_;
bool isNew_;
std::map<std::string, DataTypes> fieldDataTypes_;
std::map<std::string, std::string> fieldValues_;
private:
template<typename T>
struct getDispatcher;
};
template<>
struct Record::getDispatcher<std::string> {
static std::string impl(Record const& rec, std::string& const field) {
return rec.fieldValues_[field];
}
};
template<>
struct Record::getDispatcher<int> {
static int impl(Record const& rec, const std::string& field) {
return 0;
}
};
I think i'm doing things correctly, but still getting this error that i can't figure out. Can anyone see where i've gone wrong? Thanks.
There are no operator[] of std::map which is const, you have to use at or find:
template<>
struct Record::getDispatcher<std::string> {
static std::string impl(Record const& rec, std::string& const field) {
return rec.fieldValues_.at(field); // throw if field is not in map.
}
};
or
template<>
struct Record::getDispatcher<std::string> {
static std::string impl(Record const& rec, std::string& const field) {
auto it = rec.fieldValues_.find(field);
if (it == rec.fieldValues_.end()) {
// not found.
// Manage the case, return default value or throw.
} else {
return it->second;
}
}
};
I'm new in C++ , i use G++ compiler (Ubuntu 4.8.1-2ubuntu1~12.04) 4.8.1
i try to implement undirected wieghted Graph. by two classes Edges and Graph. but the compiler gives me this error
the compiler gives this error
/usr/include/c++/4.8/ext/new_allocator.h: In instantiation of 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...)
[with _Up = UNDIR_W_EDGE; _Args = {const UNDIR_W_EDGE&}; _Tp =
UNDIR_W_EDGE]':
/usr/include/c++/4.8/bits/alloc_traits.h:254:4: required from 'static typename
std::enable_ifAlloc>::_construct_helper<_Tp,
_Args>::value, void>::type std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&&
...) [with _Tp = UNDIR_W_EDGE; _Args = {const UNDIR_W_EDGE&}; _Alloc =
std::allocator; typename
std::enable_ifAlloc>::_construct_helper<_Tp,
_Args>::value, void>::type = void]'
/usr/include/c++/4.8/bits/alloc_traits.h:393:57: required from 'static decltype (_S_construct(__a, __p,
(forward<_Args>)(std::allocator_traits::construct::__args)...))
std::allocator_traits<_Alloc>::construct(_Alloc&, _Tp*, _Args&& ...)
[with _Tp = UNDIR_W_EDGE; _Args = {const UNDIR_W_EDGE&}; _Alloc =
std::allocator; decltype (_S_construct(__a, __p,
(forward<_Args>)(std::allocator_traits::construct::__args)...)) =
]'
/usr/include/c++/4.8/bits/stl_vector.h:906:34: required from 'void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp
= UNDIR_W_EDGE; _Alloc = std::allocator; std::vector<_Tp, _Alloc>::value_type = UNDIR_W_EDGE]'
../src/GRAPH.h:31:5: required from 'void GRAPH::addEdge(const Edge&) [with Edge = UNDIR_W_EDGE]'
../src/main.cpp:32:13: required from here
/usr/include/c++/4.8/ext/new_allocator.h:120:4: error: no matching function for call to 'UNDIR_W_EDGE::UNDIR_W_EDGE(const UNDIR_W_EDGE&)'
{ ::new((void *)__p) _Up(std::forward<Args>(_args)...); }
The Code
GRAPH.h file
#include "vector"
template <typename Edge>
class GRAPH {
private:
// Implementation-dependent code
int Vcnt;
int Ecnt;
std::vector<std::vector< Edge > > adj;
public:
GRAPH(int x):Vcnt(x),Ecnt(0) {
adj.resize(Vcnt);
}
virtual ~GRAPH();
virtual int V() const;
virtual int E() const;
virtual void addEdge(const Edge &e){
adj[e.V()].push_back(e);
adj[e.W()].push_back(e);
Ecnt++;
};
virtual std::vector< Edge > adjIterator(int) const;
};
UNDIRWEDGE.h file
class UNDIR_W_EDGE {
int v,w;
float weight;
public:
UNDIR_W_EDGE(int v, int w, float weight);
UNDIR_W_EDGE(UNDIR_W_EDGE &);
virtual ~UNDIR_W_EDGE();
virtual int V()const;
virtual int W()const;
virtual float WEIGHT()const;
virtual int CompareTo(UNDIR_W_EDGE e)const;
};
in UNDIRWEDGE.cpp
inline int UNDIR_W_EDGE::CompareTo(UNDIR_W_EDGE e)const{
if(this->weight > e.weight) return 1;
else if (this->weight < e.weight)return -1;
else return 0;
}
in main.cpp
GRAPH<UNDIR_W_EDGE> g(10);
UNDIR_W_EDGE e(0,7,0.0);
g.addEdge(e);
You don't have a copy constructor for UNDIR_W_EDGE.
The copy constructor is required inside std::vector<UNDIR_W_EDGE>, as well as in CompareTo which takes its argument by value (for some reason).
You do have this:
UNDIR_W_EDGE(UNDIR_W_EDGE &);
Presumably you intended for it to be:
UNDIR_W_EDGE(const UNDIR_W_EDGE&);