Cannot iterate a flat map - boost

I am working with a boost flat_map and trying to iterate through it, however, I cannot figure out how to create the iterator.
my_map = mySeg.find<tlsSHMMap>("temp_map").first; //fetch a pointer to the map
tlsShmemAllocator alloc_inst (mySeg.get_segment_manager());
for (boost::container::flat_map<int, tlsStorage, std::less<int>() ,alloc_inst >::const_iterator row = my_map->begin();
row != my_map->end();
++row)
{
//do stuff
}
The 'tlsStorage' is a struct that I use to store data from a database. The boost flat map is declared as follows somewhere else in the code:
boost::container::flat_map tls_temp_map = mySeg.construct<tlsSHMMap>("temp_map") (std::less<int>() ,alloc_inst); //object name
The code that I have above does not work. Here are the errors, any ideas?
src/dbm/dbm_shm_server.cc: In member function 'int redcom::dbm::ShmServer::StartServer()':
src/dbm/dbm_shm_server.cc:353:24: warning: unused variable 'tls_main_map' [-Wunused-variable]
tlsSHMMap* tls_main_map;
^
src/dbm/dbm_shm_server.cc:354:24: warning: unused variable 'tls_temp_map' [-Wunused-variable]
tlsSHMMap* tls_temp_map;
^
src/dbm/dbm_shm_server.cc: In member function 'void redcom::dbm::ShmServer::fake_notify()':
src/dbm/dbm_shm_server.cc:2023:84: error: the value of 'alloc_inst' is not usable in a constant expression
for (boost::container::flat_map<int, tlsStorage, std::less<int>() ,alloc_inst >::const_iterator row = my_map->begin();
^
src/dbm/dbm_shm_server.cc:2021:40: note: 'alloc_inst' was not declared 'constexpr'
const tlsShmemAllocator alloc_inst (mySeg.get_segment_manager());
^
src/dbm/dbm_shm_server.cc:2023:95: error: type/value mismatch at argument 4 in template parameter list for 'template<class Key, class T, class Compare, class Allocator> class boost::container::flat_map'
for (boost::container::flat_map<int, tlsStorage, std::less<int>() ,alloc_inst >::const_iterator row = my_map->begin();
^
src/dbm/dbm_shm_server.cc:2023:95: error: expected a type, got 'alloc_inst'
src/dbm/dbm_shm_server.cc:2023:113: error: invalid type in declaration before 'row'
for (boost::container::flat_map<int, tlsStorage, std::less<int>() ,alloc_inst >::const_iterator row = my_map->begin();
^
src/dbm/dbm_shm_server.cc:2023:113: error: expected ';' before 'row'
src/dbm/dbm_shm_server.cc:2023:113: error: 'row' was not declared in this scope
src/dbm/dbm_shm_server.cc:2024:37: error: expected ')' before ';' token
row != my_map->end();
^
src/dbm/dbm_shm_server.cc:2023:98: warning: unused variable 'const_iterator' [-Wunused-variable]
for (boost::container::flat_map<int, tlsStorage, std::less<int>() ,alloc_inst >::const_iterator row = my_map->begin();
^
src/dbm/dbm_shm_server.cc:2025:19: error: 'row' was not declared in this scope
++row)
^
src/dbm/dbm_shm_server.cc:2025:22: error: expected ';' before ')' token
++row)
^
distcc[31606] ERROR: compile src/dbm/dbm_shm_server.cc on localhost failed
scons: *** [debug/build/x86_64-unknown-freebsd9.2/dbm/dbm_shm_server.o] Error 1
scons: building terminated because of errors.

Your code appears to be thoroughly confused. And the errors only slightly related to the code shown...[1]
Never mind, I have figured out that in your actual code (ShmServer::fake_notify) you are declaring allocInst, nearly like you showed, but const:
const tlsShmemAllocator alloc_inst (mySeg.get_segment_manager());
Which also handsomely explains why your loop control variable has an invalid type:
error: the value of 'alloc_inst' is not usable in a constant expression
error: expected a type, got 'alloc_inst'
I mean, really, the compiler couldn't be much more explicit about it. In case this wasn't clear enough it added pretty ascii art:
for(flat_map<int, tlsStorage, std::less<int>() ,alloc_inst >::const_iterator row = my_map->begin();
So yeah... you're trying to pass an allocator as an allocator type argument? Instead, use types as template arguments. Note the use of typedefs to reduce code clutter:
typedef boost::container::flat_map<
int, tlsStorage, std::less<int>, tlsShmemAllocator> ShmTable;
typedef ShmTable::const_iterator ShmTableIt;
for(ShmTableIt rowit=my_map->begin(); rowit!=my_map->end(); ++rowit)
{
ShmTableIt::value_type const& row = *rowit;
int id = row.first;
tlsStorage const& rowData = row.second;
}
Now of course, with C++11 you could write that without all those typedefs
for(auto rowit=my_map->begin(); rowit!=my_map->end(); ++rowit)
{
int id = rowit->first;
auto& rowData = rowit->second;
}
Or even more to the point:
for(auto const& row : *my_map)
{
int id = row.first;
auto& rowData = row.second;
}
Try to reduce on cruft so you don't get overwhelmed by the code :)
[1] some points in case:
boost::container::flat_map is a template, so your declaration cannot possibly be correct. I suspect you actually have
tlsSHMMap* tls_temp_map;
Why would you give us false code? That's unrelated?
In fact, is it my_map in your actual code? or tls_temp_map? Or tls_main_map (which you don't show, but is declared and never used...)?

Related

Accessing string in a union inside a struct in C++14

Can anyone please explain how to use and access string in a union inside a structure with the help of unrestricted union?
#include <iostream>
#include <string>
using namespace std;
typedef struct {
int height;
int width;
} Page;
typedef struct {
int test;
union {
Page page;
int intVar;
string stringVar;
} VarUnion;
} VariableDataStruct;
int main()
{
VariableDataStruct structeg;
structeg.VarUnion.stringVar = "Hello";
return 0;
}
Currently getting following errors on compilation:
unionstring2.cc: In function ‘int main()’:
unionstring2.cc:22:24: error: use of deleted function ‘VariableDataStruct::VariableDataStruct()’
VariableDataStruct structeg;
^
unionstring2.cc:11:16: note: ‘VariableDataStruct::VariableDataStruct()’ is implicitly deleted because the default definition would be ill-formed:
typedef struct {
^
unionstring2.cc:11:16: error: use of deleted function ‘VariableDataStruct::::()’
unionstring2.cc:13:19: note: ‘VariableDataStruct::::()’ is implicitly deleted because the default definition would be ill-formed:
union {
^
unionstring2.cc:16:11: error: union member ‘VariableDataStruct::::stringVar’ with non-trivial ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string() [with _CharT = char; _Traits = std::char_traits; _Alloc = std::allocator]’
string stringVar;
^
unionstring2.cc:11:16: error: use of deleted function ‘VariableDataStruct::::~()’
typedef struct {
^
unionstring2.cc:13:19: note: ‘VariableDataStruct::::~()’ is implicitly deleted because the default definition would be ill-formed:
union {
^
unionstring2.cc:16:11: error: union member ‘VariableDataStruct::::stringVar’ with non-trivial ‘std::basic_string<_CharT, _Traits, _Alloc>::~basic_string() [with _CharT = char; _Traits = std::char_traits; _Alloc = std::allocator]’
string stringVar;
^
unionstring2.cc:22:24: error: use of deleted function ‘VariableDataStruct::~VariableDataStruct()’
VariableDataStruct structeg;
^
unionstring2.cc:18:11: note: ‘VariableDataStruct::~VariableDataStruct()’ is implicitly deleted because the default definition would be ill-formed:
} VariableDataStruct;
^
unionstring2.cc:18:11: error: use of deleted function ‘VariableDataStruct::::~()’
The error you're getting is not about accessing union, it's about not being able to instantiate your struct:
error: use of deleted function ‘VariableDataStruct::VariableDataStruct()’
You need to provide a constructor for your struct that sensibly initializes the union.
Unions with members with non-trivial special member functions (constructor, assignment, destructors) (such as std::string) must define these special functions as well. Since this union does not provide the designation which member is currently in use, those special member functions cannot be defined.
Use std::variant<Page, int, std::string> instead.

std::tuple and a type cartesian_product<unsigned N_n, unsigned ... N_nm1>

The following code doesn't compile, but I don't found the error (I don't unsderstand the message error).
My basic template type, 'int_mod_N', is an integer from 0 to 'N', an integer module 'N' (to represent elements of a cyclic group). This is very easy and I have constructed a library of integers represented in radix 'B', where the digits are of 'int_mod_N', and the integer is represented as 'std::basic_strings< int_mod_N >'. It works.
The problematic thing is the type I need to represent elements of a cartesian product of 'n' sets, for each of them integers module a const integer 'N_i'.
Mathematically, I want to represent elements of Z_Nn x ... x Z_N1, only the additive group.
The next code don't compile.
#include <tuple>
#include "int_mod_N_t.hpp"
template<
unsigned N_n,unsigned ... N_nm1
>
struct elem_set_t :
public
decltype(
std::tuple_cat(
std::tuple< int_mod_N_t<N_n> >{},
elem_set_t< N_nm1 ... >{}
)
)
{};
template<unsigned N_n,unsigned N_nm1>
struct elem_set_t<N_n,N_nm1> :
public
std::tuple<
int_mod_N_t<N_n> ,
int_mod_N_t<N_nm1>
>
{};
template<unsigned N_n>
struct elem_set_t<N_n> :
public
std::tuple<
int_mod_N_t<N_n>
>
{};
The error message of compiler (g++ 7.2.0), is
In file included from /tuplas_y_tipos/main.cpp:3:0:
/tuplas_y_tipos/elem_set_t.hpp: In instantiation of 'struct
elem_set_t<2, 2, 2>': /tuplas_y_tipos/main.cpp:8:20: required from
here /tuplas_y_tipos/elem_set_t.hpp:10:21: error: no matching function
for call to 'tuple_cat(std::tuple >, elem_set_t<2, 2>)'
std::tuple_cat(
~~~~~~~~~~~~~~^
std::tuple< int_mod_N_t >{},
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
elem_set_t< N_nm1 ... >{}
~~~~~~~~~~~~~~~~~~~~~~~~~
)
~ In file included from /tuplas_y_tipos/elem_set_t.hpp:1:0,
from /tuplas_y_tipos/main.cpp:3: c:\mingw\include\c++\7.2.0\tuple:1575:5: note: candidate:
template constexpr typename
std::__tuple_cat_result<_Tpls ...>::__type std::tuple_cat(_Tpls&& ...)
tuple_cat(_Tpls&&... __tpls)
^~~~~~~~~ c:\mingw\include\c++\7.2.0\tuple:1575:5: note: template argument deduction/substitution failed:
c:\mingw\include\c++\7.2.0\tuple:1572:31: error: no type named 'type'
in 'struct std::enable_if' template
elem_set_t<2,2,2> elem;
^~~~ make.exe[1]: * [tuplas_y_tipos.mk:97: Debug/main.cpp.o] Error 1 make.exe: * [Makefile:5: All] Error 2
make.exe[1]: Leaving directory '/tuplas_y_tipos'
====1 errors, 6 warnings====
I don't recommend inheriting from std::tuple at all, and for this, you don't need to.
template <unsigned ... N_ns>
using elem_set_t = std::tuple<int_mod_N_t<N_ns>...>;
If you have some methods in mind, you should have a tuple data member, not base class
template <unsigned ... N_ns>
struct elem_set_t
{
std::tuple<int_mod_N_t<N_ns>...> data;
// other members
}

clang accepts "static_cast<const int&>" using "explicit operator int() const", gcc/VS reject

Given this c++11 code: (everything remains the same compiling as c++14 or c++17)
class typeSafe {
public:
typeSafe(int tValue)
: value(tValue) {
}
explicit operator int() const {
return value;
}
private:
int value;
};
int main() {
typeSafe x{5};
typeSafe y{5};
if(static_cast<const int&>(x) == static_cast<const int&>(y)) {
}
}
The controversy is because the static_cast attempts converting to a const int&, but the explicit operator gives an int, not an int&.
clang 5.0.0 silently compiles it, with every warning turned on.
gcc rejects it, with:
typeSafe.cpp: In function ‘int main()’:
typeSafe.cpp:17:32: error: invalid static_cast from type ‘typeSafe’ to type ‘const int&’
if(static_cast<const int&>(x) == static_cast<const int&>(y)) {
^
typeSafe.cpp:17:62: error: invalid static_cast from type ‘typeSafe’ to type ‘const int&’
if(static_cast<const int&>(x) == static_cast<const int&>(y)) {
^
Visual Studio 2017 15.5 Preview 2 rejects it, with:
typeSafe.cpp(17): error C2440: 'static_cast': cannot convert from 'typeSafe' to 'const int &'
typeSafe.cpp(17): note: Reason: cannot convert from 'typeSafe' to 'const int'
typeSafe.cpp(17): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
Note if the static_cast attempts converting to an int&, then all 3 compilers reject it, with clang saying:
typeSafe.cpp:17:7: error: non-const lvalue reference to type 'int' cannot
bind to a value of unrelated type 'typeSafe'
if(static_cast<int&>(x) == static_cast<int&>(y)) {
^ ~
typeSafe.cpp:17:31: error: non-const lvalue reference to type 'int' cannot
bind to a value of unrelated type 'typeSafe'
if(static_cast<int&>(x) == static_cast<int&>(y)) {
^ ~
So, who's right and who's wrong?

C++ iterator mismatch error

I am keeping track if instances of my class using std::vector to store pointers to all of the class objects. I'm wrapping things up and want to remove the pointer in the destructor... but I am getting the following error:
Brazos.cpp:15:89: error: cannot convert 'std::vector::iterator {aka __gnu_cxx::__normal_iterator >}' to 'const char*' for argument '1' to 'int remove(const char*)'
instanceAddress.erase(std::remove(instanceAddress.begin(), instanceAddress.end(), this) instanceAddress.end());
it seems I may need to dereference the iterator... Here is my code:
std::vector<Brazos*> Brazos::instanceAddress;
Brazos::Brazos(Mano mano)
{
instanceAddress.push_back(this);
_mano = mano;
}
Brazos::~Brazos(void)
{
instanceAddress.erase(std::remove(instanceAddress.begin(), instanceAddress.end(), this) instanceAddress.end());
}
You're missing a comma:
instanceAddress.erase(std::remove(instanceAddress.begin(), instanceAddress.end(), this), instanceAddress.end());
^
Also, the error message refers to int std::remove(const char*), so make sure you have #include <algorithm> for the correct std::remove.

Type of iterator for range-based for loop

Say I have the following code:
std::vector<std::string> foo({"alice", "bob"});
for (const std::string &f : foo)
std::cout << f.size() << std::endl;
if I make a mistake and change f.size() to f->size(), I get the following error from GCC:
error: base operand of ‘->’ has non-pointer type ‘const string {aka
const std::basic_string}
Why is the actual type const std::basic_string<char> rather than const std::basic_string<char> & (reference)?
The left-hand side of -> operator is an expression. There ain't no such thing as an expression with a reference type:
5p5 If an expression initially has the type “reference to T” (8.3.2, 8.5.3), the type is adjusted to T prior to any further analysis. The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression.

Resources