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.
Related
consider the following code:
#include <future>
#include <boost/optional.hpp>
struct S {
std::promise<int> p;
};
void f() {
boost::optional<S> o = std::move(S());
}
it fails to compile because somewhere deep inside boost::optional implementation it tries to use the copy constructor of S.
is there some way to overcome this and move the promise without copying it?
I tried to explicitly add a move constructor to S
S(S&& s): p(std::move(s.p)) {}
S() = default;
to no avail.
compiler error message:
In file included from /usr/include/boost/optional.hpp:15:0,
from /tmp/iotpromise.cpp:2:
/usr/include/boost/optional/optional.hpp: In instantiation of ‘void boost::optional_detail::optional_base<T>::construct(boost::optional_detail::optional_base<T>::argument_type) [with T = S; boost::optional_detail::optional_base<T>::argument_type = const S&]’:
/usr/include/boost/optional/optional.hpp:230:20: required from ‘boost::optional_detail::optional_base<T>::optional_base(boost::optional_detail::optional_base<T>::argument_type) [with T = S; boost::optional_detail::optional_base<T>::argument_type = const S&]’
/usr/include/boost/optional/optional.hpp:526:46: required from ‘boost::optional<T>::optional(boost::optional<T>::argument_type) [with T = S; boost::optional<T>::argument_type = const S&]’
/tmp/iotpromise.cpp:9:39: required from here
/usr/include/boost/optional/optional.hpp:346:8: error: use of deleted function ‘S::S(const S&)’
new (m_storage.address()) internal_type(val) ;
^
/tmp/iotpromise.cpp:4:8: note: ‘S::S(const S&)’ is implicitly deleted because the default definition would be ill-formed:
struct S {
^
/tmp/iotpromise.cpp:4:8: error: use of deleted function ‘std::promise<_Res>::promise(const std::promise<_Res>&) [with _Res = int]’
In file included from /tmp/iotpromise.cpp:1:0:
/usr/include/c++/4.9/future:977:7: note: declared here
promise(const promise&) = delete;
^
Using Boost 1.55.0, GCC 6.3
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.
I'm having some trouble when using coeffRef() with a CWiseUnaryView function, but only when the function is declared as const
Reproducible example:
#include <Eigen/Core>
struct dummy_Op {
EIGEN_EMPTY_STRUCT_CTOR(dummy_Op)
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const double&
operator()(const double &v) const { return v; }
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE double&
operator()(double &v) const { return v; }
};
void foo(Eigen::MatrixXd &out)
{
//Compiles
Eigen::CwiseUnaryView<dummy_Op, Eigen::MatrixXd> view(out);
view.coeffRef(0,0);
//Doesn't Compile
const Eigen::CwiseUnaryView<dummy_Op, Eigen::MatrixXd> const_view(out);
const_view.coeffRef(0,0);
}
Returns:
<source>: In function 'void foo(Eigen::MatrixXd&)':
<source>:21:28: error: passing 'const Eigen::CwiseUnaryView<dummy_Op,
Eigen::Matrix<double, -1, -1> >' as 'this' argument discards qualifiers
[-fpermissive]
const_view.coeffRef(0,0);
^
In file included from /opt/compiler-explorer/libs/eigen/v3.3.4/Eigen/Core:413,
from <source>:1:
/opt/compiler-explorer/libs/eigen/v3.3.4/Eigen/src/Core/DenseCoeffsBase.h:340:33: note:
in call to 'Eigen::DenseCoeffsBase<Derived, 1>::Scalar&
Eigen::DenseCoeffsBase<Derived, 1>::coeffRef(Eigen::Index, Eigen::Index)
[with Derived = Eigen::CwiseUnaryView<dummy_Op, Eigen::Matrix<double,
-1, -1> >; Eigen::DenseCoeffsBase<Derived, 1>::Scalar = double; Eigen::Index = long int]'
EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
^~~~~~~~
Compiler returned: 1
Compiler explorer: https://godbolt.org/z/kPHPuC
The side-effect of this, is that the multiplication of two (non-const) CWiseUnaryViews also fails, see example here: https://godbolt.org/z/JYQb3d
The bottom line is that you're calling a non-const method of a constant instance. The (first) coeffRef that is being called is the one (and only) in DenseCoeffsBase.h (DenseCoeffsBase<Derived, WriteAccessors>), which is not const qualified. The DenseCoeffsBase<Derived, ReadOnlyAccessors> class does not have a coeffRef method. You can get around this error (and get a warning) if you enable the -fpermissive compiler flag.
In the dense case, you probably want to use the operator()(Index, Index) method anyway, which does have a const qualified version. I just noticed the documentation explicitly says to use that method anyway, even for the non-const version. This is obviously not going to return a const reference, but at least in your example as a double, it shouldn't matter too much.
CwiseUnaryView is intended to be used for L-value like expression, e.g.,
MatrixXcd A;
A.real() = something; // `A.real()` is writable
If you want to apply an element-wise functor and use it as an R-value, you should use CwiseUnaryOp instead:
void foo(Eigen::MatrixXd &out)
{
Eigen::CwiseUnaryOp<dummy_Op, Eigen::MatrixXd> view1(out);
// shorter:
auto view2 = out.unaryExpr(dummy_Op());
Eigen::MatrixXd result = view1 * view2;
// or directly write: out.unaryExpr(dummy_Op()) * out.unaryExpr(dummy_Op());
}
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,
The following code is a snippet of a tuple-like class where it is possible to get a reference to a given type in the tuple, or if that type is not found, the provided default value will be returned instead.
If the default value is a lvalue a reference must be returned, if the default value is a rvalue then a rvalue must be returned.
The following code illustrates the problem I'm having:
struct Foo {
Foo(int d) : data(d) {}
template <typename T, typename TT>
const TT get_or_default(TT&& t) const {
return data;
}
template <typename T, typename TT>
TT get_or_default(TT&& t) {
return data;
}
int data;
};
int main(int argc, char* argv[]) {
int i = 6;
const Foo foo1(5);
Foo foo2(5);
// compile error
foo1.get_or_default<int>(i);
// works
foo1.get_or_default<int>(5);
foo2.get_or_default<int>(i) = 4;
foo2.get_or_default<char>('a');
return 0;
}
When compiling this I get the following error:
cxx.cxx:6:20: error: binding of reference to type 'int' to a value of type 'const int' drops qualifiers
return data;
^~~~
cxx.cxx:23:14: note: in instantiation of function template specialization 'Foo::get_or_default<int, int &>' requested here
foo1.get_or_default<int>(i);
^
1 error generated.
There is a special rule for template argument deduction when the function parameter is of type T&& where T is a template parameter. That rule is:
If the function argument is an lvalue of type U, then U& is used in place of U for type deduction in this case.
It's used to allow perfect forwarding. Basically, it means that T&& for a template parameter T is a "universal reference."
In your case, since i is indeed an lvalue, TT is deduced to int&. Applying a const to that is ignored (it would apply to the reference itself, not to the type referred to), so the fucntion instantiated from the template looks something like this:
int& get_or_default(int& t) const {
return data;
}
And since the function is const, data is considered const as well and so it cannot bind to a non-const reference.