I am having problem to define a subclass member as index member
Is this possible
For the following code
namespace bmi = boost::multi_index;
namespace bip = boost::interprocess;
struct UsersKey {
uint64_t IMSI;
};
struct UsersVal {
uint64_t IMSI;
};
struct HashEntry{
UsersKey key;
UsersVal val;
}
typedef bmi::hashed_unique<bmi::tag<struct IMSI_tag>, bmi::member<HashEntry, uint64_t , &HashEntry::UsersKey::IMSI>, boost::hash<uint64_t>, std::equal_to<uint64_t> > hashed_by_IMSI;
typedef
bmi::indexed_by< hashed_by_IMSI > UsersKey_hash_indices;
typedef boost::multi_index::multi_index_container<
HashEntry,
UsersKey_hash_indices>
> GlobalHash;
I get the following error
error: no member named 'UsersKey' in 'HashEntry'; did you mean simply 'UsersKey'?
Here is a link to online code http://coliru.stacked-crooked.com/a/d736557edf615fc2
The C++ pointer to member function syntax does not allow to designate members inside members as you intend to do here. One simple option is to use the provided global_fun key extractor as shown at http://coliru.stacked-crooked.com/a/c57625bfb1d5acfa
Best,
Related
I am trying to send a vector of "struct" per message, but when defining the message field the following error is generated:
Entering directory '/home/veins/workspace.omnetpp/veins/src'
veins/modules/application/clustertraci/ClusterTraCI11p.cc
veins/modules/application/clustertraci/ClusterTraCI11p.cc:160:40: error: no viable conversion from 'vector' to 'const vector'
frameOfUpdate->setUpdateTable(updateTable);
I read chapter 6 of the OMnet ++ manual, but I don't understand how to solve this problem.
Implementation with error
Message Code (MyMessage.msg):
cplusplus {{
#include "veins/base/utils/Coord.h"
#include "veins/modules/messages/BaseFrame1609_4_m.h"
#include "veins/base/utils/SimpleAddress.h"
#include <iostream>
#include <vector>
struct updateTableStruct {
int car;
char update;
};
typedef std::vector<updateTableStruct> UpdateTable;
}}
namespace veins;
class BaseFrame1609_4;
class noncobject Coord;
class noncobject UpdateTable;
class LAddress::L2Type extends void;
packet ClusterMessageUpdate extends BaseFrame1609_4 {
LAddress::L2Type senderAddress = -1;
int serial = 0;
UpdateTable updateTable;
MyApp.cc:
void ClusterTraCI11p::handleSelfMsg(cMessage* msg) {
if (ClusterMessage* frame = dynamic_cast<ClusterMessage*>(msg)) {
ClusterMessageUpdate* frameOfUpdate = new ClusterMessageUpdate;
populateWSM(frameOfUpdate, CH2);
frameOfUpdate->setSenderAddress(myId);
frameOfUpdate->setUpdateTable(updateTable);
sendDelayedDown(frameOfUpdate, uniform(0.1, 0.02));
}
else {
DemoBaseApplLayer::handleSelfMsg(msg);
}
}
Part of code for analysis in MyApp.h:
struct updateTableStruct {
int car;
char update;
};
typedef std::vector<updateTableStruct> UpdateTable;
UpdateTable updateTable;
You experience a type mismatch: In MyApp.h you define the type UpdateTable, and you do so in MyMessage.h. While these both types have the same content and appear to have the same name, I assume this is not actually the case: one type is UpdateTable (defined at global scope in the file generated based on your message) and the other is MyApp::UpdateTable (defined in your application, assuming you are omitting the class definition in the code you show).
Therefore, the types are different, and they cannot be converted into each other implicitly. In this case this might appear a bit counter-intuitive, as they have exactly the same definition, but they do not have the same name. In the following example the reasoning is shown: Two different types that share the same definition should not necessarily be implicitly convertible into each other:
struct Coordinate {
int x;
int y;
};
struct Money {
int dollars;
int cents;
};
void test() {
Coordinate c;
Money m = c;
}
Gives the following error message:
test.cc:13:8: error: no viable conversion from 'Coordinate' to 'Money'
Money m = c;
^ ~
test.cc:6:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Coordinate' to 'const Money &' for 1st argument
struct Money {
^
test.cc:6:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'Coordinate' to 'Money &&' for 1st argument
struct Money {
^
1 error generated.
Edit:
The solution to your specific problem is to remove one of the definitions and include the remaining definition when using it, so you can either remove the UpdateTable definition from the message and include the App header instead, or remove the UpdateTable definition from the App and include the message instead.
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.
struct A { int x; };
int main() {
int A::* pt = &A::x;
return 0;
}
what does int A::* mean exactly? I have never seen C++ syntax like this.
Just like other traits, you specify the template argument and use the value member.
std::is_member_object_pointer<decltype(pa) >::value
what does int A::* mean exactly?
That is a type declaration of a member object pointer to an int member of the class A.
I would like to use instances of a non-proto class as proto terminals
for all purposes. To enable this functionality, I use is_terminal
metafunction and pass it to BOOST_PROTO_DEFINE_OPERATORS().
This actually defines the operators, so the following expression makes
an expression tree, as expected:
non_proto_obj * proto_obj; // creates proto expression tree
However, I cannot do this:
non_proto_obj = proto_obj; // no operator=
non_proto_obj[proto_obj]; // no operator[]
While the opposite does compile:
proto_obj = non_proto_obj;
proto_obj[non_proto_obj];
It seems that my object is not convertible to proto expression.
Is there any workaround for this issue?
(On Coliru)
#include <iostream>
#include <boost/proto/proto.hpp>
#include <boost/mpl/int.hpp>
namespace mpl = boost::mpl;
namespace proto = boost::proto;
using proto::_;
template<typename Expr>
struct my_expression;
struct my_domain : proto::domain<proto::generator<my_expression> >
{};
template<int I> struct placeholder {};
template<typename Expr>
struct my_expression : proto::extends<Expr, my_expression<Expr>, my_domain>
{
explicit my_expression(Expr const &expr = Expr()) :
my_expression::proto_extends(expr)
{}
BOOST_PROTO_EXTENDS_USING_ASSIGN(my_expression<Expr>)
};
const my_expression<proto::terminal<placeholder<1>>::type> _1;
namespace app
{
struct non_proto_type
{};
template <typename T>
struct is_terminal : mpl::false_
{};
template<>
struct is_terminal<non_proto_type> : mpl::true_
{};
BOOST_PROTO_DEFINE_OPERATORS(is_terminal, my_domain)
non_proto_type non_proto;
}
int main()
{
_1 = app::non_proto; // ok, builds temporary proto expression
//app::non_proto = _1; // does not compile! no operator=
_1[app::non_proto]; // ok
//app::non_proto[_1]; // does not compile! no operator[]
(+app::non_proto)[_1]; // ok! applying unary + to make a proto expression first, then operator[] is available
}
There is no work around.
The C++ language places restrictions on some operators. Notably, the indexing (operator[]), assignment and function call operators must be defined as a non-static member function.
This means that there can never be an implicit conversion on the "left-hand-side" operand in an expression of the type lhs[rhs]. End of story.
All EDSL frameworks I know have helper functions to decorate your "literal" expression as a domain expression, e.g. boost::phoenix::val(x) or boost::spirit::x3::as_parser(x).
For example
#define MEMBERS(...) using Members = decltype(std::make_tuple(__VA_ARGS__));
struct A
{
int i;
float f;
MEMBERS(i, f); // Error
};
How to use a macro to define the tuple type by using members other than their types?