Boost Directed Graph - add_edge - stored_edge_property - c++11

typedef boost::adjacency_list<
boost::vecS, boost::vecS, boost::directedS, NodeInfo, EdgeInfo> Graph;
Graph g(10);
EdgeInfo be;
add_edge(0,1,be,g);
Error:
use of deleted function 'boost::detail::stored_edge_property
Changing "undirected" to "directed" causes error under linux (gcc/4.9.2) while compiles fine on windows visual studio express 2013. Boost: 1.59.0.
The culprit seems to be add_edge
Is there a quick fix?
Some forums have pointed to BGL incompatibilities with C++11 asking coders to revert to C++03. Is there an alternative?
Thanks

I see no problem:
Live On Coliru: gcc 4.9
Live On Coliru: gcc 4.8
Live On Coliru: gcc 5.2
Live On Coliru: gcc 5.2
Live On Coliru: clang 3.7
With the following graphs:
#include <boost/graph/adjacency_list.hpp>
struct NodeInfo { };
struct EdgeInfo { };
int main() {
using namespace boost;
{
typedef adjacency_list<vecS, vecS, directedS, NodeInfo, EdgeInfo> Graph;
Graph g(10);
}
{
typedef adjacency_list<vecS, vecS, undirectedS, NodeInfo, EdgeInfo> Graph;
Graph g(10);
}
}
This tells me your problem is likely with the NodeInfo/EngeInfo types. If they are not copyable etc. this could lead to errors. MSVC might be more lenient than the standard requires (they frequently are in areas of name lookup and reference binding).

Related

vector of maps of non-copyable objects fails to compile in MSVC

The following code (also in https://godbolt.org/z/NSG6Qz) compiles fine in gcc, clang and Visual Studio 2013, but does not compile in recent MSVC versions:
#include <map>
#include <vector>
class MoveOnly {
public:
MoveOnly() {}
MoveOnly(const MoveOnly&) = delete;
MoveOnly& operator=(const MoveOnly&) = delete;
MoveOnly(MoveOnly&&);
MoveOnly& operator=(MoveOnly&&);
};
int main() {
std::vector<std::map<int, MoveOnly>> vecOfMaps;
std::map<int, MoveOnly> map;
vecOfMaps.push_back(std::move(map));
}
The compilation in all MSVC versions in godbolt fails, in v19.22 with these errors (excerpt):
error C2280: 'std::pair<const _Kty,_Ty>::pair(const std::pair<const _Kty,_Ty> &)':
attempting to reference a deleted function
[...]
note: while compiling class template member function
'std::map<int,MoveOnly,std::less<int>,std::allocator<std::pair<const _Kty,_Ty>>>::map(
const std::map<_Kty,_Ty,std::less<int>,std::allocator<std::pair<const _Kty,_Ty>>> &)'
MSVC does not have problems pushing non-copyable objects into a std::map. Pushing non-copyable objects into std::vector works as well. But pushing the map of non-copyable objects into the vector fails.
Why doesn't this compile?
Is there a workaround that can be applied to the MoveOnly class to make this code compile in MSVC, without losing the non-copyable attribute?

CUDA 8.0: Compile Error with Template Friend in Namespace

I noticed that the following code compiles with g++/clang++-3.8 but not with nvcc:
#include <tuple> // not used, just to make sure that we have c++11
#include <stdio.h>
namespace a {
template<class T>
class X {
friend T;
};
}
I get the following compile error:
/usr/local/cuda-8.0/bin/nvcc -std=c++11 minimum_cuda_test.cu
nvcc warning : The 'compute_20', 'sm_20', and 'sm_21' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning).
minimum_cuda_test.cu:7:10: error: ‘T’ in namespace ‘::’ does not name a type
friend T;
Interestingly, this works with nvcc:
#include <tuple> // not used, just to make sure that we have c++11
#include <stdio.h>
template<class T>
class X {
friend T;
};
Is this a bug in the compiler? I thought nvcc would internally use g++ or clang as a compiler so I am confused why this would work with my local compiler but not with nvcc.
In both cases, the code is being compiled by g++. However, when you pass a .cu file to nvcc, it puts the code through the CUDA C++ front end before passing it to the host compiler. Looking at CUDA 8 with gcc 4.8, I see that the code has been transformed from
namespace a {
template<class T>
class X {
friend T;
};
}
to
namespace a {
template< class T>
class X {
friend ::T;
};
You can see that the front end has replaced the templated friend with an equivalent, but with a prepended anonymous namespace, which is breaking the compilation. I'm not a C++ language lawyer, but this would appear to me to be a bug in the CUDA front end. I would suggest reporting it to NVIDIA.

Boost Polygon Serialization

I am using boost geometry in my project, and I need to serialize polygons. I have been using boost serialization without problems for many boost data types, but boost geometry seems that currently does not support serialization, as I cannot find any header inside serialization folder.
Is there any well known method to achieve this?
Thanks.
EDIT: Binary Serialization Example in: Boost Polygon Serialization: Ring
I agree, it is weird that Boost.Geometry does not support Boost.Serialization. Probably it is hard to support all possible combinations of template parameters, or maybe they did not bother as WKT is already provided.
At least in the case of "default" container types it is trivial to add such functionality. The code below implements it and is fully functional.
Below I assume you use a custom class (QPoint from Qt) as your point class. Code for other point types will be almost identical to mine.
First, you add a serialization for the Point class:
#include <QPoint>
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/register/point.hpp>
BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(QPoint, int, cs::cartesian, x, y, setX, setY);
typedef QPoint MyPoint;
namespace boost {
namespace serialization {
template<class Archive>
void serialize(Archive & ar, MyPoint& pt, const unsigned int version) {
ar & boost::serialization::make_nvp("x", pt.rx() );
ar & boost::serialization::make_nvp("y", pt.ry() );
}
} //namespace serialization
} //namespace boost
Next you add serialization for Ring and Polygon. Here I use the fact that Ring and Polygon are essentially std::vector(s) of points and rings respectively and the serialization for std::vector is built-in in Boost.Serialization.
#include <boost/serialization/vector.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/ring.hpp>
//change template flags as you are pleased but ring and polygon has to be
//in correspondence w.r.t. to "closed" and "clockwise" policies
typedef boost::geometry::model::ring<MyPoint, false, true> MyRing;
typedef boost::geometry::model::polygon<MyPoint, false, true> MyPolygon;
namespace boost {
namespace serialization {
//Default ring<MyPoint> simply inherits from std::vector<MyPoint>,
//its serialization is trivial and no implementation is needed.
//Default polygon<MyPoint> gives direct access to outer ring and the container of inner rings
template<class Archive>
void serialize(Archive & ar, MyPolygon& poly, const unsigned int version) {
ar & boost::serialization::make_nvp("outer", poly.outer());
ar & boost::serialization::make_nvp("inners", poly.inners());
}
} //namespace serialization
} //namespace boost
That's it, you are done, now you can use MyPolygon with Boost.Serialize as any other class:
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
void foo_out(std::ostream & oss, const MyPolygon & poly)
{
boost::archive::xml_oarchive oa(oss);
oa & BOOST_SERIALIZATION_NVP(poly);
}
void foo_in(std::istream & iss, MyPolygon & poly)
{
boost::archive::xml_iarchive ia(iss);
ia & BOOST_SERIALIZATION_NVP(poly);
}
Enjoy!
Boost.Geometry does not support Boost.Serialization. You can read and write WKT (well-known text), this is a standardized ASCII format used by many databases too. See for example:
http://en.wikipedia.org/wiki/Well-known_text
There is also WKB (well-known binary) but that is not yet 100% supported. However, for polygons it is supported.

NDK C++11, call to deleted constructor error

I have a class called RenderCommand:
class RenderCommand
{
public:
RenderCommandType commandType;
RenderCommand() : commandType(RenderCommandTypeNone) {};
virtual ~RenderCommand() {};
};
I then have a queue of these RenderCommands which stores unique_ptrs to them:
typedef std::deque<std::unique_ptr<RenderCommand>> RenderQueue;
Finally in a section of code, I create a vector of these RenderQueues, and try to resize it:
std::vector<RenderQueue> queues;
queues.resize(4);
The resize line is giving me a few issues. In clang I get the error message:
call to deleted constructor of 'std::unique_ptr<RenderCommand, std::default_delete<RenderCommand> >'
With GCC 4.8, I just get a whole bunch of errors similar to
required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::_Deque_iterator<std::unique_ptr<RenderCommand>, const std::unique_ptr<RenderCommand>&, const std::unique_ptr<RenderCommand>*>; _ForwardIterator = std::_Deque_iterator<std::unique_ptr<RenderCommand>, std::unique_ptr<RenderCommand>&, std::unique_ptr<RenderCommand>*>; _Tp = std::unique_ptr<RenderCommand>]'
This compiles fine in Visual Studio 2012 however so I'm a little lost. I appreciate any help you guys can give!
EDIT: RenderCommandType is just an enum:
enum RenderCommandType
{
RenderCommandTypeNone = 0,
RenderCommandTypeBeginRepeat,
RenderCommandTypeEndRepeat,
RenderCommandTypeBeginScene,
RenderCommandTypeEndScene,
//etc
};
EDIT2: Ok this seems to be a std::deque problem, changing RenderQueue to:
typedef std::vector<std::unique_ptr<RenderCommand>> RenderQueue;
works. Also removing references to my own class and just using an int still doesn't work (unless like above I replace deque with vector):
std::vector<std::deque<std::unique_ptr<int>>> tempQueue;
tempQueue.resize(4);
:-/
I simplified your example to
#include <deque>
#include <vector>
struct A {
A(const A&) = delete;
};
void f()
{
std::vector<std::deque<A> > q;
q.resize(4);
}
With g++ 4.6, this example compiles fine. From g++ 4.7 on however, it prints a lot of error messages, finally resulting in the mentioned
error: use of deleted function ‘A::A(const A&)’
Replacing deque with vector or list doesn't show this behaviour.
So, it seems this is either a regression from g++ 4.6 to 4.7 or a correction of a previous bug. In any case, I filed a bug report with g++, see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59192

Why is this simplest C++0x code not valid?

I encountered a weird problem just now.
The source code is simple and self-evident as follows:
#include <vector>
#include <iostream>
#include <functional>
using namespace std;
using namespace std::tr1;
template<class T_>
void show_size(T_ coll)
{
cout << coll.size();
}
int main()
{
vector<int> coll;
coll.push_back(1);
show_size(ref(coll));
return 0;
}
The VC++ 2010 reports:
error C2039: 'size' : is not a member of 'std::tr1::reference_wrapper<_Ty>'
As we know, reference_wrapper can automatically convert itself to its underlying type, here is vector<int>. Why is such simple code not valid?
No it can't that's the whole point of the reference wrapper, because it doesn't decay from the reference, unless explicitly requested using .get()
Edit: don't mix up the boosts reference wrapper with the standard one, the boost one actually has implicit conversion (but the target functionality is a little bit different)

Resources