I am using the optional feature for the 1st time, any idea what is wrong in this code I wish to retrieve the value from the tuple which is stored in retCode
#include <iostream>
#include <experimental/optional>
std::experimental::optional<std::tuple<uint16_t, uint32_t, uint32_t>> addEntity();
std::experimental::optional<std::tuple<uint16_t, uint32_t, uint32_t>> addEntity() {
uint32_t ipR = 1111;
uint32_t ipU = 2222;
uint16_t entityId = 0;
return std::make_tuple(entityId, ipR, ipU);
}
int main()
{
auto retCode = addEntity();
std::cout<<std::get<0>(retCode)<<std::endl;
return 0;
}
Compilation Errors
g++ experiment.cpp
In file included from /usr/include/c++/7/bits/move.h:54:0,
from /usr/include/c++/7/bits/nested_exception.h:40,
from /usr/include/c++/7/exception:143,
from /usr/include/c++/7/ios:39,
from /usr/include/c++/7/ostream:38,
from /usr/include/c++/7/iostream:39,
from experiment.cpp:1:
/usr/include/c++/7/type_traits: In instantiation of ‘struct std::is_trivially_destructible<std::tuple<short unsigned int, unsigned int, unsigned int> >’:
/usr/include/c++/7/experimental/optional:203:5: required from ‘class std::experimental::fundamentals_v1::optional<std::tuple<short unsigned int, unsigned int, unsigned int> >’
There's no implicit conversion from optional<T> to T, you need to extract the value.
int main()
{
auto retCode = addEntity();
std::cout<<std::get<0>(retCode.value())<<std::endl; // can throw std::bad_optional_access
return 0;
}
Unless you have other places which require addEntity to return an optional tuple, not just places where you call addEntity to initialise an optional tuple, it should just return a tuple.
Related
I have a class with a constructor but the compilation fails with the error:
error: use of deleted function 'std::atomic<long unsigned int>::atomic(const std::atomic<long unsigned int>&)'
I'm struggling to understand what this error means. I've been trying to update some code from using tbb::atomic to using std::atomic, and this error wasn't appearing before with tbb::atomic.
The bit of code that upsets the compiler is:
#include <boost/aligned_storage.hpp>
template <typename T>
class Holder<T,true>
{
public:
//! Construct a value (there mustn't be one already)
template <typename ARG>
void Construct(const ARG &arg) { new(Raw()) T(arg); }
private:
typename boost::aligned_storage<sizeof(T), boost::alignment_of<T>::value>::type impl;
void *Raw() { return &impl; }
};
Specifically the line:
void Construct(const ARG &arg) { new(Raw()) T(arg); }
I'd be very grateful if anyone could help me understand what is going on.
EDIT:
Full error message:
holder.hpp:75:34: error: use of deleted function 'std::atomic<long unsigned int>::atomic(const std::atomic<long unsigned int>&)'
75 | void Construct(const T &arg) { new(Raw()) T(arg); }
| ^~~~~~~~~~~~~~~~~
In file included from /include/TPtools/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp:19,
from /include/TPtools/boost/smart_ptr/detail/sp_counted_base.hpp:48,
from /include/TPtools/boost/smart_ptr/detail/shared_count.hpp:29,
from /include/TPtools/boost/smart_ptr/shared_ptr.hpp:28,
from /include/TPtools/boost/shared_ptr.hpp:17,
from movegate.cpp:14:
/pkgsData/gcc-v9.3.0p1/Linux/RHEL6.0-2013-x86_64/include/c++/9.3.0/atomic:824:7: note: declared here
824 | atomic(const atomic&) = delete;
| ^~~~~~
holder.hpp: In instantiation of 'void Holder<T, true>::Construct(const T&) [with T = std::atomic<long unsigned int>; T = std::atomic<long unsigned int>]':
element.hpp:185:9: required from 'void Element<PRESENT, ABSENT>::Accessor<PRESENCE>::MakePresentImpl(const ARG&) const [with ARG = std::atomic<long unsigned int>; PRESENCE = Cluster<Element<std::atomic<long unsigned int>, Link>, true>::NonLockingPresence; PRESENT = std::atomic<long unsigned int>; ABSENT = Link]'
element.hpp:119:7: required from 'Element<PRESENT, ABSENT>::PresentResult Element<PRESENT, ABSENT>::Accessor<PRESENCE>::MakePresent(const ARG&) const [with ARG = std::atomic<long unsigned int>; PRESENCE = Cluster<Element<std::atomic<long unsigned int>, Link>, true>::NonLockingPresence; PRESENT = std::atomic<long unsigned int>; ABSENT = Link; Element<PRESENT, ABSENT>::PresentResult = std::atomic<long unsigned int>&]'
dispenser.hpp:78:5: required from 'Index Dispenser<T>::Insert(const T&) [with T = std::atomic<long unsigned int>]'
I have a Register function which takes a std::function<void(const uint8_t* data, size_t len)> as a parameter. I want to use the member function of an object as the target.
I found this question according to which the answer is to use std::bind to bind the first first argument (the implicit this pointer) to the actual object pointer and then use it as the std::function argument.
This however doesn't work anymore in neither C++11, C++14 nor C++17?
Consider the following test program.
#include <iostream>
#include <cstdint>
#include <functional>
void Register(std::function<void(const uint8_t* data, size_t len)> func) {
//Dummy - directly call into function
func(nullptr, 0);
}
class TestClass {
public:
void TestRegister() {
Register(
std::bind(&TestClass::TestTarget, this, std::placeholders::_1)
);
}
void TestTarget(const uint8_t* data, size_t len) {
(void) data;
(void) len;
std::cout << "Hello there" << std::endl;
}
};
int main() {
TestClass testObj;
testObj.TestRegister();
return 0;
}
When compiling for -std=c++17 this throws a rather cryptic error message (I have no idea what it's trying to say here with Wrong number of arguments for pointer-to-member):
In file included from /home/max/Documents/TestingFunctions/main.cpp:3:0:
/usr/include/c++/7/functional: In instantiation of ‘struct std::_Bind_check_arity<void (TestClass::*)(const unsigned char*, long unsigned int), TestClass*, const std::_Placeholder<1>&>’:
/usr/include/c++/7/functional:854:12: required from ‘struct std::_Bind_helper<false, void (TestClass::*)(const unsigned char*, long unsigned int), TestClass*, const std::_Placeholder<1>&>’
/usr/include/c++/7/functional:875:5: required by substitution of ‘template<class _Func, class ... _BoundArgs> typename std::_Bind_helper<std::__is_socketlike<_Func>::value, _Func, _BoundArgs ...>::type std::bind(_Func&&, _BoundArgs&& ...) [with _Func = void (TestClass::*)(const unsigned char*, long unsigned int); _BoundArgs = {TestClass*, const std::_Placeholder<1>&}]’
/home/max/Documents/TestingFunctions/main.cpp:14:78: required from here
/usr/include/c++/7/functional:841:7: error: static assertion failed: Wrong number of arguments for pointer-to-member
static_assert(_Varargs::value
^~~~~~~~~~~~~
/home/max/Documents/TestingFunctions/main.cpp: In member function ‘void TestClass::TestRegister()’:
/home/max/Documents/TestingFunctions/main.cpp:14:26: error: could not convert ‘std::bind(_Func&&, _BoundArgs&& ...) [with _Func = void (TestClass::*)(const unsigned char*, long unsigned int); _BoundArgs = {TestClass*, const std::_Placeholder<1>&}; typename std::_Bind_helper<std::__is_socketlike<_Func>::value, _Func, _BoundArgs ...>::type = std::_Bind<void (TestClass::*(TestClass*, std::_Placeholder<1>))(const unsigned char*, long unsigned int)>](((TestClass*)this), std::placeholders::_1)’ from ‘std::_Bind_helper<false, void (TestClass::*)(const unsigned char*, long unsigned int), TestClass*, const std::_Placeholder<1>&>::type {aka std::_Bind<void (TestClass::*(TestClass*, std::_Placeholder<1>))(const unsigned char*, long unsigned int)>}’ to ‘std::function<void(const unsigned char*, long unsigned int)>’
std::bind(&TestClass::TestTarget, this, std::placeholders::_1)
~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Replacing the TestRegister function with one that does the exact same thing in a lambda expression compiles and runs without problems.
void TestRegister() {
Register(
[this](const uint8_t* data, size_t len) {
TestTarget(data, len);
}
);
}
Question: Why does the std::bind approach from the linked question not work? Was this feature removed or do I have an error in my code?
Your function Register expects a function with two parameters, but you try to pass to it a function with one placeholded parameter.
void TestRegister() {
Register(
std::bind(&TestClass::TestTarget, this, std::placeholders::_1, std::placeholders::_2)
);
}
Your function takes two parameters, while you are only passing one placeholder.
std::bind(&TestClass::TestTarget, this, std::placeholders::_1, std::placeholders::_2);
I tried:
#include <vector>
int main () {
std::vector<int> v;
int size = v.size;
}
but got the error:
cannot convert 'std::vector<int>::size' from type 'std::vector<int>::size_type (std::vector<int>::)() const noexcept' {aka 'long unsigned int (std::vector<int>::)() const noexcept'} to type 'int'
Casting the expression to int like this:
#include <vector>
int main () {
std::vector<int> v;
int size = (int)v.size;
}
also yields an error:
error: invalid use of member function 'std::vector<_Tp, _Alloc>::size_type std::vector<_Tp, _Alloc>::size() const [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]' (did you forget the '()' ?)
Last I tried:
#include <vector>
int main () {
std::vector<int> v;
int size = v.size();
}
which gave me:
warning: implicit conversion loses integer precision
How can I fix this?
In the first two cases, you simply forgot to actually call the member function (!, it's not a value) std::vector<int>::size like this:
#include <vector>
int main () {
std::vector<int> v;
auto size = v.size();
}
Your third call
int size = v.size();
triggers a warning, as not every return value of that function (usually a 64 bit unsigned int) can be represented as a 32 bit signed int.
int size = static_cast<int>(v.size());
would always compile cleanly and also explicitly states that your conversion from std::vector::size_type to int was intended.
Note that if the size of the vector is greater than the biggest number an int can represent, size will contain an implementation defined (de facto garbage) value.
I am compiling a c++ code on a linux ubuntu with g++4.8.1 and boost 1.55.0.
My program uses a class A, which has a member table which is an unsigned long long array. The same class has other members which are simple int. I am using boost to serialize my data.
My code work and compile all fine, if I serialize all but the table in A.
However it does not compile if I try to serialize table. I get the following error:
/usr/local/include/boost/serialization/access.hpp: In instantiation of ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = long long unsigned int]’:
/usr/local/include/boost/serialization/access.hpp: In instantiation of ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = long long unsigned int]’:
/usr/local/include/boost/serialization/serialization.hpp:69:69: required from ‘void boost::serialization::serialize(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = long long unsigned int]’
/usr/local/include/boost/serialization/serialization.hpp:128:27: required from ‘void boost::serialization::serialize_adl(Archive&, T&, unsigned int) [with Archive = boost::archive::text_oarchive; T = long long unsigned int]’
/usr/local/include/boost/archive/detail/oserializer.hpp:152:5: required from ‘void boost::archive::detail::oserializer<Archive, T>::save_object_data(boost::archive::detail::basic_oarchive&, const void*) const [with Archive = boost::archive::text_oarchive; T = long long unsigned int]’
/usr/local/include/boost/archive/detail/oserializer.hpp:101:1: required from ‘class boost::archive::detail::oserializer<boost::archive::text_oarchive, long long unsigned int>’
/usr/local/include/boost/archive/detail/oserializer.hpp:214:5: required from ‘boost::archive::detail::pointer_oserializer<Archive, T>::pointer_oserializer() [with Archive = boost::archive::text_oarchive; T = long long unsigned int]’
/usr/local/include/boost/serialization/singleton.hpp:106:7: [ skipping 95 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/local/include/boost/archive/detail/oserializer.hpp:314:44: required from ‘static void boost::archive::detail::save_non_pointer_type<Archive>::invoke(Archive&, T&) [with T = Metapop; Archive = boost::archive::text_oarchive]’
/usr/local/include/boost/archive/detail/oserializer.hpp:525:24: required from ‘void boost::archive::save(Archive&, T&) [with Archive = boost::archive::text_oarchive; T = Metapop]’
/usr/local/include/boost/archive/detail/common_oarchive.hpp:69:40: required from ‘void boost::archive::detail::common_oarchive<Archive>::save_override(T&, int) [with T = Metapop; Archive = boost::archive::text_oarchive]’
/usr/local/include/boost/archive/basic_text_oarchive.hpp:80:9: required from ‘void boost::archive::basic_text_oarchive<Archive>::save_override(T&, int) [with T = Metapop; Archive = boost::archive::text_oarchive]’
/usr/local/include/boost/archive/detail/interface_oarchive.hpp:63:9: required from ‘Archive& boost::archive::detail::interface_oarchive<Archive>::operator<<(T&) [with T = Metapop; Archive = boost::archive::text_oarchive]’
simulation.cpp:1403:9: required from here
/usr/local/include/boost/serialization/access.hpp:118:9: error: request for member ‘serialize’ in ‘t’, which is of non-class type ‘long long unsigned int’
t.serialize(ar, file_version);
^
I have read aroud that if I used vectors or/and an other data type it would work. However it is critical for me (for speed) to use a raw array of unsigned long long. Any idea ?
Thnaks a lot for you help !
Serializing unsigned long long arrays works for me using gcc 4.7.2 with boost 1.49, gcc 4.2.1 with boost 1.55, and clang 3.4 with boost 1.55:
#include <sstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/access.hpp>
#include <boost/version.hpp>
struct Foo {
unsigned long long bar[3];
template<class Archive>
void serialize(Archive& ar, const unsigned int /*version*/) {
ar & bar;
}
};
std::ostream& operator<<(std::ostream& os, const Foo& foo) {
return os << foo.bar[0] << ' ' << foo.bar[1] << ' ' << foo.bar[2];
}
int main() {
std::cout << "Boost version " << BOOST_LIB_VERSION << '\n';
Foo before;
before.bar[0] = 0;
before.bar[1] = 1;
before.bar[2] = 2;
std::cout << "before: " << before << '\n';
std::ostringstream os;
{
boost::archive::text_oarchive oa(os);
oa << before;
}
Foo after;
{
std::istringstream is(os.str());
boost::archive::text_iarchive ia(is);
ia >> after;
}
std::cout << "after: " << after << '\n';
return 0;
}
Here's gcc 4.8 with boost 1.55 on Coliru, also works.
If you are using a pointer to an allocated array, then I think that is your problem. I don't believe you can serialize a bare pointer to a primitive, and I'm sure you can't serialize a bare pointer to an array of primitives because there is no way for serialization to know how many elements a pointer points to.
I would use a std::vector over an allocated array because there is no speed disadvantage in doing so. However, if you really want to allocate your own array then you can serialize it with the boost::serialization::make_array() wrapper like this:
#include <iostream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/array.hpp>
struct Foo {
size_t dataSize;
unsigned long long *data;
Foo()
: dataSize(3)
, data(new unsigned long long[dataSize]) {
}
~Foo() {
delete[] data;
}
// TODO: Production code should disallow default copy constructor
// and assignment operator.
template<class Archive>
void serialize(Archive& ar, const unsigned int /*version*/) {
ar & dataSize;
ar & boost::serialization::make_array(data, dataSize);
}
};
int main() {
Foo foo;
foo.data[0] = 0;
foo.data[1] = 1;
foo.data[2] = 2;
boost::archive::text_oarchive oa(std::cout);
oa << foo;
return 0;
}
It turns out that this question was not about unsigned long long at all, but is essentially a duplicate of boost serialization, deserialization of raw C arrays.
I am having trouble aliasing the function boost::make_iterator_range
(I would like to hide boost behind an alias in case this particular library gets adopted into the standard sometime in the future.)
Is there any way this can be made to work?
#include <boost/range/iterator_range.hpp>
void Foo()
{
}
template< typename T >
void Bar()
{ }
template< typename T >
void Bar(char c)
{ }
void (&FooAlias)() = Foo; // ok
void (&BarAlias)() = Bar<int>; // ok
// boost::iterator_range<const size_t*> (&MakeIterRangeAlias)(const size_t*,const size_t*) =
// boost::make_iterator_range<const size_t*>; // not ok
int main(int argc, char** argv)
{
const size_t v[] = { 3, 5, 1, 5, 29, 15 };
boost::iterator_range<const size_t*> r
= boost::make_iterator_range( std::begin( v ), std::end( v )); // want to alias this
return 0;
}
The error message is:
In file included from /usr/include/boost/iterator/iterator_categories.hpp:15:0,
from /usr/include/boost/iterator/detail/facade_iterator_category.hpp:7,
from /usr/include/boost/iterator/iterator_facade.hpp:14,
from /usr/include/boost/range/iterator_range_core.hpp:23,
from /usr/include/boost/range/iterator_range.hpp:13,
from sandbox.cpp:2:
/usr/include/boost/mpl/eval_if.hpp: In instantiation of ‘boost::mpl::eval_if_c<true, boost::range_const_iterator<const long unsigned int*>, boost::range_mutable_iterator<const long unsigned int* const> >’:
/usr/include/boost/range/iterator.hpp:63:63: instantiated from ‘boost::range_iterator<const long unsigned int* const>’
sandbox.cpp:20:10: instantiated from here
/usr/include/boost/mpl/eval_if.hpp:60:31: error: no type named ‘type’ in ‘boost::mpl::eval_if_c<true, boost::range_const_iterator<const long unsigned int*>, boost::range_mutable_iterator<const long unsigned int* const> >::f_ {aka struct boost::range_const_iterator<const long unsigned int*>}’
/usr/include/boost/mpl/eval_if.hpp: In instantiation of ‘boost::mpl::eval_if_c<false, boost::range_const_iterator<const long unsigned int*>, boost::range_mutable_iterator<const long unsigned int*> >’:
/usr/include/boost/range/iterator.hpp:63:63: instantiated from ‘boost::range_iterator<const long unsigned int*>’
sandbox.cpp:20:10: instantiated from here
/usr/include/boost/mpl/eval_if.hpp:60:31: error: no type named ‘type’ in ‘boost::mpl::eval_if_c<false, boost::range_const_iterator<const long unsigned int*>, boost::range_mutable_iterator<const long unsigned int*> >::f_ {aka struct boost::range_mutable_iterator<const long unsigned int*>}’
sandbox.cpp:20:10: error: invalid initialization of non-const reference of type ‘void (&)(const size_t*, const size_t*) {aka void (&)(const long unsigned int*, const long unsigned int*)}’ from an rvalue of type ‘<unresolved overloaded function type>’
make: *** [sandbox] Error 1
Using function pointers is a suboptimal way alias a function. It is not as flexible as the original (it can no longer be a template) and you now need to know the exact signature of the function, which may or may not be stable.
Instead try this approach.
template< typename ... Args >
auto MakeIterRangeAlias( Args&& ... args ) -> decltype( /* copy return line here */ )
{
return boost::make_iterator_range( std::forward<Args>(args)... );
}
With almost no work on your part the alias supports the exact signature of the original. Even if it dramatically changes, you're still set. Further, unlike the function pointer approach the optimizer will be able to trivially inline MakeIterRangeAlias so that there is no runtime overhead.