How to send a "struct" vector per message? - omnet++

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.

Related

Specialized template accepting constructor parameter when only default constructor defined

So, I have this template class and its specialization.
#include <iostream>
using namespace std;
template<bool> struct CompileTimeChecker{
CompileTimeChecker(...); //constructor, can accept any number of parameters;
};
//specialized template definition
template<> struct CompileTimeChecker<false> {
//default constructor, body empty
};
Case 1:
In the main function I am defining a local class called ErrorA. When I create a temporary of CompileTimeChecker<false> with temporary object of ErrorA fed as an initializer, the compiler is not detecting any error.
int main()
{
class ErrorA {};
CompileTimeChecker<false>(ErrorA()); //Case 1;
CompileTimeChecker<false>(int()); //Case 2;
return 0;
}
Case 2:
Next I feed it with temporary object of type int, and suddenly the compiler recognizes the issue (there is no constructor that takes args in the specialized template CompileTimeChecker<false>)
main.cpp:30:36: error: no matching function for call to ‘CompileTimeChecker::CompileTimeChecker(int)’ CompileTimeChecker<false>(int());
main.cpp:21:23: note: candidate: constexpr CompileTimeChecker::CompileTimeChecker()
template<> struct CompileTimeChecker<false> {
^~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:21:23: note: candidate expects 0 arguments, 1 provided
Why does it not recognize the issue in case 1?
CompileTimeChecker<false>(ErrorA());
does not create a temporary of type CompileTimeChecker<false>, passing a temporary ErrorA() to its constructor. Rather, it declares a function named ErrorA, taking no parameters and returning CompileTimeChecker<false> . See also: most vexing parse.
On the other hand, CompileTimeChecker<false>(int()); cannot be parsed as a declaration, so it does unambiguously create a temporary of type CompileTimeChecker<false>.
The easiest way out is to use braces in place of parens to indicate initialization:
CompileTimeChecker<false>{ErrorA{}};

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.

C++11: Variadic template deduction logic

I have the following construct:
template <class... Args>
class some_class
{
public:
some_class() = default;
some_class(Args...) = delete;
~some_class() = default;
};
template<>
class some_class<void>
{
public:
some_class() = default;
~some_class() = default;
};
The reason for this is that I just want to allow the users to create objects using the default constructor, so for example:
some_class<int,float> b;
should work but
some_class<int,float> c(1,3.4);
should give me a compilation error.
At some point in time I also needed to create templates based on void hence, the specialization for void:
some_class<void> a;
But by mistake I have typed:
some_class<> d;
And suddenly my code stopped compiling and it gave me the error:
some_class<Args>::some_class(Args ...) [with Args = {}]’ cannot be
overloaded
some_class(Args...) = delete;
So here comes the question: I feel that I am wrong that I assume that some_class<> should be deduced to the void specialization... I just don't know why. Can please someone explain why some_class<> (ie: empty argument list) is different from some_class<void>? (A few lines from the standard will do :) )
https://ideone.com/o6u0D6
void is a type like any other (an incomplete type, to be precise). This means it can be used as a template argument for type template parameters normally. Taking your class template, these are all perfectly valid, and distinct, instantiations:
some_class<void>
some_class<void, void>
some_class<void, void, void>
some_class<void, char, void>
In the first case, the parameter pack Args has one element: void. In the second case, it has two elements: void and void. And so on.
This is quite different from the case some_class<>, in which case the parameter pack has zero elements. You can easily demonstrate this using sizeof...:
template <class... Pack>
struct Sizer
{
static constexpr size_t size = sizeof...(Pack);
};
int main()
{
std::cout << Sizer<>::size << ' ' << Sizer<void>::size << ' ' << Sizer<void, void>::size << std::endl;
}
This will output:
0 1 2
[Live example]
I can't really think of a relevant part of the standard to quote. Perhaps this (C++11 [temp.variadic] 14.5.3/1):
A template parameter pack is a template parameter that accepts zero or more template arguments. [ Example:
template<class ... Types> struct Tuple { };
Tuple<> t0; // Types contains no arguments
Tuple<int> t1; // Types contains one argument: int
Tuple<int, float> t2; // Types contains two arguments: int and float
Tuple<0> error; // error: 0 is not a type
—end example ]

C++11 class in std::map as Value with private constructors

Here is the simplified version of the class which is stored as value in a map which works fine in VS2008 (note that all members are private):
class Value{
friend class FriendClass;
friend class std::map<std::string, Value>;
friend struct std::pair<const std::string, Value>;
friend struct std::pair<std::string, Value>;
Value() {..}
Value(Value const& other) {..}
... rest members...
};
Code (called from FriendClass, so this can reach private constructors) :
FriendClass::func()
{
std::map<const std::string, Value> map;
map.insert(std::make_pair(std::string("x"), Value()));
}
This compiles w/o any error in VS2008, but fails on VS2015/C++11:
file.cpp(178): error C2664: 'std::_Tree_iterator>>> std::_Tree>::insert(std::_Tree_const_iterator>>>,const std::pair &)': cannot convert argument 1 from 'std::pair' to 'std::pair &&'
with
[
_Kty=std::string,
_Ty=Value,
_Pr=std::less,
_Alloc=std::allocator>
]
and
[
_Kty=std::string,
_Ty=Value
]
file.cpp(178): note: Reason: cannot convert from 'std::pair' to 'std::pair'
with
[
_Kty=std::string,
_Ty=Value
]
file.cpp(178): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
If I make the Value copy constructor public, it compiles fine in VS2015 as well. But that was private with purpose, and only made available for std::map and std::pair. However, it seems in C++11 additional friend access are also necessary to declare. Which are these?
Thank you.
I don't have access to the compilers you mentioned, but here's what I'm seeing on g++ 5.3.
Consider the following essentially-same version of your question:
#include <map>
#include <utility>
class foo
{
friend std::pair<const int, foo>;
foo(const foo &other){}
public:
foo(){}
};
int main()
{
using map_t = std::map<int, foo>;
map_t m;
m.insert(std::make_pair(2, foo()));
// m.emplace(2, foo());
}
(The default ctor is public, but that's non-essential and just makes the example shorter.)
In main, note the two lines
m.insert(std::make_pair(2, foo()));
// m.emplace(2, foo());
Reversing the comments builds fine, but the version shown doesn't:
/usr/include/c++/5/bits/stl_pair.h: In instantiation of ‘constexpr std::pair<_T1, _T2>::pair(_U1&&, const _T2&) [with _U1 = int; <template-parameter-2-2> = void; _T1 = int; _T2 = foo]’:
/usr/include/c++/5/bits/stl_pair.h:281:72: required from ‘constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&) [with _T1 = int; _T2 = foo; typename std::__decay_and_strip<_T2>::__type = foo; typename std::__decay_and_strip<_Tp>::__type = int]’
stuff.cpp:21:34: required from here
stuff.cpp:9:2: error: ‘foo::foo(const foo&)’ is private
foo(const foo &other){}
^
Looking at the source code std_pair.h shows that indeed it is trying to call the copy constructor. Unfortunately, you friended std::pair, but not std::make_pair.
The emplace version doesn't have this problem, but I suspect that this is implementation dependent. In general, if you want a container to store a completely opaque class, I would suggest that you use a container of std::shared_ptrs to them. This allows you to completely specify which function/class can create/copy objects in your own code, and makes no assumptions on the library's code.

multi_index index member of sub class member

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,

Resources