How can I use gsl::span and indicate ownership? - c++

I want to write a function which:
Takes a pointer as a parameter
Takes a length as a parameter
Owns the memory pointed to by the pointer (e.g. maybe it releases it, or constructs a unique_ptr to it in some data structure etc.)
Now, if I wanted 1+2 I would just use gsl::span. And if wanted 1+3 I would use owner<T*>. But what should I do when I want all three? Should I pass an owner<gsl::span<T>>? Something else?
Notes:
You may not assume the pointer is into the heap.
std::vector is requiring too much. The function should not require the caller to construct an std::vector.

One option would be to define your own abstract base class to encapsulate the data. Something like:
template<typename T>
class DataHolder {
public:
virtual ~DataHolder() = default;
virtual gsl::span<T> get() const = 0;
};
Then your function could look something like:
void foo(std::unique_ptr<DataHolder<int>> data) {
if (!data)
return;
for (auto v : data->get())
std::cout << v << " ";
}
The caller can then implement the base class with any container they want to. There will be a small cost of polymophism but not on a per-element basis.
If you don't want to pay for polymorphism, perhaps you could make your function accept a template parameter.
template<typename DataHolder>
void foo(DataHolder data) {
for (auto v : data())
std::cout << v << " ";
}
where the implicit interface for DataHolder could be satisfied by something like:
struct VectorHolder {
std::vector<int> data;
gsl::span<const int> operator()() const { return data; }
};
or if you really don't want to use vector. You could use something like this (as suggested by #utnapistim):
struct ArrayHolder {
std::unique_ptr<int[]> data;
ptrdiff_t length;
gsl::span<const int> operator()() const { return {data.get(), length}; }
};

Related

Const correctness in struct initialization

I'm playing with C++ and const-correctness right now.
Assume you have the following structure
template <typename T>
struct important_structure {
public:
T* data;
int a;
important_structure(const T& el, int a);
void change();
};
template <typename T>
void important_structure<T>::change() {
//alter data field in some way
}
template <typename T>
important_structure <T>::important_structure(const T& el, int a) : data(&el), a(a) //error line {
};
int main() {
important_structure<int>* s = new important_structure<int>{5, 3};
}
When compiling with std=c++11, the compiler returns the following error:
invalid conversion from ‘const int*’ to ‘int*’
Now, I know it's unsafe to cast a const int* to int*. The problem is that I have a data structure and I don't want to put the field data as a constant.
However, I don't want to remove the const qualifier in the constructor since, I think, it's informative for future developers: it clearly says that el won't be modified by the function. Still the field data may be modified by some other function in important_structure.
My question is: How can I deal with fields which are initialized in the costructor and altered in some other function?
Most of const correctness deals with simple answers, but no question (I think) deals with scenarios where a const parameter is passed to a data structure and then such data structure is altered by someone else.
Thanks for any kind reply
passing el as a const reference doesn't just mean the function will not change el during the run of the function, it means because of this function call, el won't be changed at all. And by putting the address of el into non-const data, you violate that promise.
So, the clean solution, if you indeed want to change data, is removing the const. since it is not informative to future developers, but misleading. Casting away the const would be very bad here.
Let's use a simple class as T type of important_struct:
class Data
{
public:
Data() : something(0){}
Data(int i) : something(i){}
Data(const Data & d) : something(d.something){}
//non-const method: something can be modified
void changeSomething(int s){ something += s; }
//const method: something is read-only
int readSomething() const { return something; }
private:
int something;
};
This class has a very simple, yet well encapsulated, status, i.e. the int something field, which is accessed through methods in a very controlled way.
Let (a simplified version of) important_structure hold an instance of Data as a private field:
template <typename T>
struct important_structure
{
public:
important_structure(T * el);
void change();
int read() const;
private:
T* data;
};
We can assign a Data instance to an important_structure instance this way:
important_structure<Data> s(new Data());
The instance is assigned in construction:
template <typename T>
important_structure <T>::important_structure(T * el) : data(el) {}
Now the great question: do important_structure take ownership of the Data instances it holds? The answer must be made clear in documentation.
If it is yes, important_structure must take care of memory cleanup, e.g. a destructor like this one is required:
template<typename T>
important_structure<T>::~important_structure()
{
delete data;
}
Notice that, in this case:
Data * p = new Data()
// ...
important_structure<Data> s(p);
//p is left around ...
another pointer to the Data istance is left around. What if someone mistakenly call delete on it? Or, even worse:
Data d;
// ...
important_structure<Data> s(&p); //ouch
A much better design would let important_structure own its own Data instance :
template <typename T>
struct important_structure
{
public:
important_structure();
void change();
// etc ...
private:
T data; //the instance
};
but this is maybe simplistic or just unwanted.
One could let important_structure copy the instance it will own:
template<typename T>
important_structure<T>::important_structure(const T &el)
{
data = el;
}
the latter being the constructor provided in the question: the object passed won't be touched, but copied. Obviously, there are two identical Data objects around, now. Again, the result could not be what we needed in the first place.
There is a third way, in the middle: the object is instantiated outside the owner, and moved to it, using move semantics.
As an example, let's give Data a move assignment operator:
Data & operator=(Data && d)
{
this->something = d.something;
d.something = 0;
return *this;
}
and let important_structure provide a constructor which accepts an rvalue reference of T:
important_structure(T && el)
{
data = std::move(el);
}
One can still pass a Data instance using a temporary as the required rvalue:
important_structure<Data> s(Data(42));
or an existing one, providing the required reference from an lvalue, thanks to std::move:
Data d(42);
// ...
important_structure<Data> x(std::move(d));
std::cout << "X: " << x.read() << std::endl;
std::cout << "D: " << d.readSomething() << std::endl;
In this second example, the copy held by important_structure is considered the good one while the other is left in a valid but unspecified state, just to follow the standard library habits.
This pattern is, IMHO, more clearly stated right in code, expecially if considered that this code will not compile:
Data d(42);
important_structure<Data> x (d);
Whoever wants an instance of important_structure must provide a temporary Data instance or explicitly move an existing one with std::move.
Now, let the important_structure class be a container, as you asked in comment, so that data is somehow accessible from outside. Let's give a method like this to the important_structure class:
const T & owneddata() { return data; }
Now, we can use data const methods like this:
important_structure<Data> s(Data(42));
std::cout << s.owneddata().readSomething() << std::endl;
but calls to `Data' non-const methods will not compile:
s.owneddata().changeSomething(1000); //not compiling ...
If in need of it (hope not), expose a non-const reference:
T & writablereference() { return data; }
Now the data field is at full disposal:
s.writablereference().changeSomething(1000); //non-const method called
std::cout << s.owneddata().readSomething() << std::endl;
Using const T& el and data(&el) is a really bad idea, because it implies that you could write:
new important_structure<int>{5, 3};
But to write new important_structure<int>{5, 3}; would result in data holding an address that would no longer be valid immediately after calling the constructor.
If you want that the point data can be changed, but that the value where the pointer points to cannot be changed, then you want to write it that way:
template <typename T>
struct important_structure {
public:
T const * data;
int a;
important_structure(T const * el, int a);
void change();
};
template <typename T>
void important_structure<T>::change() {
//alter data field in some way
}
template <typename T>
important_structure <T>::important_structure( T const * el, int a) : data(el), a(a) { //error line
};
int main() {
int i = 5;
important_structure<int>* s = new important_structure<int>{&i, 3};
}

Get Value of Void* C++

I have a void pointer and I would like to get the content of what the pointer refers to.
void class :: method(void * pointer)
{
cout<<pointer; // The address which the pointer refers to.
cout<<?; //The content of where the pointer refers to.
}
The original type of pointer is unknown.
EDIT: The goal is to allow create a "generic method" which gets any type of argument, and do the same actions for each.
The limitation is that the method is virtual and therefore I cannot use template method.
You need to cast the void* back to its original type (ie. before it was cast to void*). Then you can dereference the pointer and use what it's pointing to.
Eg. :
void fun(void* ptr) {
int* iptr = (int*) ptr;
std::cout << *iptr;
}
int* iptr = new int(42);
fun(iptr);
One way to do this in a way that fits your specific use case, is to pass on the type information with the object using a generic type like boost::any :
#include <iostream>
#include <string>
#include <boost/any.hpp>
class Foo {
public :
virtual void fun(const boost::any& obj) {
if (typeid(int) == obj.type()) {
std::cout << boost::any_cast<int>(obj) << std::endl;
}
else if (typeid(std::string) == obj.type()) {
std::cout << boost::any_cast<std::string>(obj) << std::endl;
}
else {
std::cout << "unsupported type" << std::endl;
}
}
};
int main(void) {
Foo foo;
int i = 42;
std::string s = "str";
float f = 1.1f;
foo.fun(i);
foo.fun(s);
foo.fun(f);
return 0;
}
But that can get very verbose, depending on how many types you want to support.
This is impossible. The types in C++ are (mostly) a compile-time property. At runtime, types are unknown (they are erased).
However, RTTI exist, notably for instances of some class containing virtual methods.
There is no possible trick in general. You could redesign your program by having some kind of variant type, or by having a common root class from which all your objects inherit, etc etc, or by using union types (better have your own discriminated unions).
Put it another way: when the compiler see a void* pointer, it does not even know the size of the data pointed by that pointer.
Future C++ standards might propose some std::any container.
Maybe you could have something like a cheap discriminated union class like
class Int_or_String {
const bool isint;
union {
int n;
std::string s;
};
Int_or_String(const int i) : isint(true), n(i) {};
Int_or_String(const std::string &st): isint(false), s(st) {};
~Int_or_String() { if (isint) n=0; else
/*not sure*/ s.std::string::~std::string(); };
// much more is missing
};
I'm not even sure of the syntax to explicitly destroy a union member.
See e.g. this question on calling destructors explicitly
Perhaps the Qt object model might inspire you. Look also into its QVariant
The usual way is to define a root class in your program and adopt the convention that all your objects are inheriting this root class (or even that all your meaningful data are in objects derived from that root class). This requires a redesign of the whole thing.
So you would decide that your root class is e.g
class Root {
public:
virtual void out(std::ostream&s) =0;
virtual ~Root() =0;
/// other common methods
};
static inline std::ostream& operator << (std::ostream&o, const Root &r)
{ r.out(o); return o; }
class Integer : public Root {
const int num;
public:
Integer(int n) : Root(), num(n) {};
void out (std::ostream &o) { o << num ; };
/// etc...
}; // end class Num
class String : public Root {
const std::string str;
public:
String(const std::string& s) : Root(), str(s) {};
void out (std::ostream &o) { o << str ; };
/// etc...
}; // end class String

shared_ptr<T> to shared_ptr<T const> and vector<T> to vector<T const>

I'm trying to define a good design for my software which implies being careful about read/write access to some variables. Here I simplified the program for the discussion. Hopefully this will be also helpful to others. :-)
Let's say we have a class X as follow:
class X {
int x;
public:
X(int y) : x(y) { }
void print() const { std::cout << "X::" << x << std::endl; }
void foo() { ++x; }
};
Let's also say that in the future this class will be subclassed with X1, X2, ... which can reimplement print() and foo(). (I omitted the required virtual keywords for simplicity here since it's not the actual issue I'm facing.)
Since we will use polymorphisme, let's use (smart) pointers and define a simple factory:
using XPtr = std::shared_ptr<X>;
using ConstXPtr = std::shared_ptr<X const>;
XPtr createX(int x) { return std::make_shared<X>(x); }
Until now, everything is fine: I can define goo(p) which can read and write p and hoo(p) which can only read p.
void goo(XPtr p) {
p->print();
p->foo();
p->print();
}
void hoo(ConstXPtr p) {
p->print();
// p->foo(); // ERROR :-)
}
And the call site looks like this:
XPtr p = createX(42);
goo(p);
hoo(p);
The shared pointer to X (XPtr) is automatically converted to its const version (ConstXPtr). Nice, it's exactly what I want!
Now come the troubles: I need a heterogeneous collection of X. My choice is a std::vector<XPtr>. (It could also be a list, why not.)
The design I have in mind is the following. I have two versions of the container: one with read/write access to its elements, one with read-only access to its elements.
using XsPtr = std::vector<XPtr>;
using ConstXsPtr = std::vector<ConstXPtr>;
I've got a class that handles this data:
class E {
XsPtr xs;
public:
E() {
for (auto i : { 2, 3, 5, 7, 11, 13 }) {
xs.emplace_back(createX(std::move(i)));
}
}
void loo() {
std::cout << "\n\nloo()" << std::endl;
ioo(toConst(xs));
joo(xs);
ioo(toConst(xs));
}
void moo() const {
std::cout << "\n\nmoo()" << std::endl;
ioo(toConst(xs));
joo(xs); // Should not be allowed
ioo(toConst(xs));
}
};
The ioo() and joo() functions are as follow:
void ioo(ConstXsPtr xs) {
for (auto p : xs) {
p->print();
// p->foo(); // ERROR :-)
}
}
void joo(XsPtr xs) {
for (auto p: xs) {
p->foo();
}
}
As you can see, in E::loo() and E::moo() I have to do some conversion with toConst():
ConstXsPtr toConst(XsPtr xs) {
ConstXsPtr cxs(xs.size());
std::copy(std::begin(xs), std::end(xs), std::begin(cxs));
return cxs;
}
But that means copying everything over and over.... :-/
Also, in moo(), which is const, I can call joo() which will modify xs's data. Not what I wanted. Here I would prefer a compilation error.
The full code is available at ideone.com.
The question is: is it possible to do the same but without copying the vector to its const version? Or, more generally, is there a good technique/pattern which is both efficient and easy to understand?
Thank you. :-)
I think the usual answer is that for a class template X<T>, any X<const T> could be specialized and therefore the compiler is not allow to simply assume it can convert a pointer or reference of X<T> to X<const T> and that there is not general way to express that those two actually are convertible. But then I though: Wait, there is a way to say X<T> IS A X<const T>. IS A is expressed via inheritance.
While this will not help you for std::shared_ptr or standard containers, it is a technique that you might want to use when you implement your own classes. In fact, I wonder if std::shared_ptr and the containers could/should be improved to support this. Can anyone see any problem with this?
The technique I have in mind would work like this:
template< typename T > struct my_ptr : my_ptr< const T >
{
using my_ptr< const T >::my_ptr;
T& operator*() const { return *this->p_; }
};
template< typename T > struct my_ptr< const T >
{
protected:
T* p_;
public:
explicit my_ptr( T* p )
: p_(p)
{
}
// just to test nothing is copied
my_ptr( const my_ptr& p ) = delete;
~my_ptr()
{
delete p_;
}
const T& operator*() const { return *p_; }
};
Live example
There is a fundamental issue with what you want to do.
A std::vector<T const*> is not a restriction of a std::vector<T*>, and the same is true of vectors containing smart pointers and their const versions.
Concretely, I can store a pointer to const int foo = 7; in the first container, but not the second. std::vector is both a range and a container. It is similar to the T** vs T const** problem.
Now, technically std::vector<T const*> const is a restriction of std::vector<T>, but that is not supported.
A way around this is to start workimg eith range views: non owning views into other containers. A non owning T const* iterator view into a std::vector<T *> is possible, and can give you the interface you want.
boost::range can do the boilerplate for you, but writing your own contiguous_range_view<T> or random_range_view<RandomAccessIterator> is not hard. It gets fancy ehen you want to auto detect the iterator category and enable capabilities based off that, which is why boost::range contains much more code.
Hiura,
I've tried to compile your code from repo and g++4.8 returned some errors.
changes in main.cpp:97 and the remaining lines calling view::create() with lambda function as the second argument.
+add+
auto f_lambda([](view::ConstRef_t<view::ElementType_t<Element>> const& e) { return ((e.getX() % 2) == 0); });
std::function<bool(view::ConstRef_t<view::ElementType_t<Element>>)> f(std::cref(f_lambda));
+mod+
printDocument(view::create(xs, f));
also View.hpp:185 required additional operator, namely:
+add+
bool operator==(IteratorBase const& a, IteratorBase const& b)
{
return a.self == b.self;
}
BR,
Marek Szews
Based on the comments and answers, I ended up creating a views for containers.
Basically I defined new iterators. I create a project on github here: mantognini/ContainerView.
The code can probably be improved but the main idea is to have two template classes, View and ConstView, on an existing container (e.g. std::vector<T>) that has a begin() and end() method for iterating on the underlying container.
With a little bit of inheritance (View is a ConstView) it helps converting read-write with to read-only view when needed without extra code.
Since I don't like pointers, I used template specialization to hide std::shared_ptr: a view on a container of std::shared_ptr<T> won't required extra dereferencing. (I haven't implemented it yet for raw pointers since I don't use them.)
Here is a basic example of my views in action.

C++ Push Multiple Types onto Vector

Note: I know similar questions to this have been asked on SO before, but I did not find them helpful or very clear.
Second note: For the scope of this project/assignment, I'm trying to avoid third party libraries, such as Boost.
I am trying to see if there is a way I can have a single vector hold multiple types, in each of its indices. For example, say I have the following code sample:
vector<something magical to hold various types> vec;
int x = 3;
string hi = "Hello World";
MyStruct s = {3, "Hi", 4.01};
vec.push_back(x);
vec.push_back(hi);
vec.push_back(s);
I've heard vector<void*> could work, but then it gets tricky with memory allocation and then there is always the possibility that certain portions in nearby memory could be unintentionally overridden if a value inserted into a certain index is larger than expected.
In my actual application, I know what possible types may be inserted into a vector, but these types do not all derive from the same super class, and there is no guarantee that all of these types will be pushed onto the vector or in what order.
Is there a way that I can safely accomplish the objective I demonstrated in my code sample?
Thank you for your time.
The objects hold by the std::vector<T> need to be of a homogenous type. If you need to put objects of different type into one vector you need somehow erase their type and make them all look similar. You could use the moral equivalent of boost::any or boost::variant<...>. The idea of boost::any is to encapsulate a type hierarchy, storing a pointer to the base but pointing to a templatized derived. A very rough and incomplete outline looks something like this:
#include <algorithm>
#include <iostream>
class any
{
private:
struct base {
virtual ~base() {}
virtual base* clone() const = 0;
};
template <typename T>
struct data: base {
data(T const& value): value_(value) {}
base* clone() const { return new data<T>(*this); }
T value_;
};
base* ptr_;
public:
template <typename T> any(T const& value): ptr_(new data<T>(value)) {}
any(any const& other): ptr_(other.ptr_->clone()) {}
any& operator= (any const& other) {
any(other).swap(*this);
return *this;
}
~any() { delete this->ptr_; }
void swap(any& other) { std::swap(this->ptr_, other.ptr_); }
template <typename T>
T& get() {
return dynamic_cast<data<T>&>(*this->ptr_).value_;
}
};
int main()
{
any a0(17);
any a1(3.14);
try { a0.get<double>(); } catch (...) {}
a0 = a1;
std::cout << a0.get<double>() << "\n";
}
As suggested you can use various forms of unions, variants, etc. Depending on what you want to do with your stored objects, external polymorphism could do exactly what you want, if you can define all necessary operations in a base class interface.
Here's an example if all we want to do is print the objects to the console:
#include <iostream>
#include <string>
#include <vector>
#include <memory>
class any_type
{
public:
virtual ~any_type() {}
virtual void print() = 0;
};
template <class T>
class concrete_type : public any_type
{
public:
concrete_type(const T& value) : value_(value)
{}
virtual void print()
{
std::cout << value_ << '\n';
}
private:
T value_;
};
int main()
{
std::vector<std::unique_ptr<any_type>> v(2);
v[0].reset(new concrete_type<int>(99));
v[1].reset(new concrete_type<std::string>("Bottles of Beer"));
for(size_t x = 0; x < 2; ++x)
{
v[x]->print();
}
return 0;
}
In order to do that, you'll definitely need a wrapper class to somehow conceal the type information of your objects from the vector.
It's probably also good to have this class throw an exception when you try to get Type-A back when you have previously stored a Type-B into it.
Here is part of the Holder class from one of my projects. You can probably start from here.
Note: due to the use of unrestricted unions, this only works in C++11. More information about this can be found here: What are Unrestricted Unions proposed in C++11?
class Holder {
public:
enum Type {
BOOL,
INT,
STRING,
// Other types you want to store into vector.
};
template<typename T>
Holder (Type type, T val);
~Holder () {
// You want to properly destroy
// union members below that have non-trivial constructors
}
operator bool () const {
if (type_ != BOOL) {
throw SomeException();
}
return impl_.bool_;
}
// Do the same for other operators
// Or maybe use templates?
private:
union Impl {
bool bool_;
int int_;
string string_;
Impl() { new(&string_) string; }
} impl_;
Type type_;
// Other stuff.
};

Map of boost function of different types?

i was wondering if there was a way to do this in C++?
void func1(const std::string& s)
{
std::cout << s << std::endl;
}
void func2(int me)
{
std::cout << me << std::endl;
}
int main()
{
std::map<std::string, boost::function< ??? > > a_map;
a_map["func1"] = &func1;
a_map["func1"]("HELLO");
}
Is there any way to do what i have above using boost function and a map?
There are ways to store the functions, the problem is, in order to be able to call the function with the desired argument you'd have to know the calling signature of the function anyways, and if you have that information, you might as well use separate maps, or use a more complicated object than boost::function.
If you're willing to do a bit of work and have a finite number of signatures, you could just do something like this:
class MultiFunc
{
protected:
MultiFunc() {}
public:
typedef void (*stringFunc)(const std::string&);
typedef void (*intFunc)(int);
static MultiFunc *Create(stringFunc function);
static MultiFunc *Create(intFunc function);
virtual void operator()(const string &) { throw exception(); }
virtual void operator()(int) { throw exception(); }
virtual ~MultiFunc();
};
class MultiFuncString : public MultiFunc
{
private:
stringFunc Function;
public:
MultiFuncString(stringFunc function) : Function(function) {}
virtual void operator()(const string &arg) { Function(arg); }
};
class MultiFuncInt : public MultiFunc
{
private:
intFunc Function;
public:
MultiFuncInt(intFunc function) : Function(function) {}
virtual void operator()(int arg) { Function(arg); }
};
MultiFunc *MultiFunc::Create(MultiFunc::stringFunc function)
{
return new MultiFuncString(function);
}
MultiFunc *MultiFunc::Create(MultiFunc::intFunc function)
{
return new MultiFuncInt(function);
}
void func1(const std::string& s)
{
std::cout << s << std::endl;
}
void func2(int me)
{
std::cout << me << std::endl;
}
int main()
{
map<string, MultiFunc *> a_map;
a_map["func1"] = MultiFunc::Create(&func1);
(*a_map["func1"])("Hello");
a_map["func2"] = MultiFunc::Create(&func2);
(*a_map["func2"])(3);
// Remember to delete the MultiFunc object, or use smart pointers.
}
This outputs:
Hello
3
Unfortunately, you can't make templated virtual functions or you easily generalize this all.
You probably can't use the std::map since it is a homogenous container. Try, something like boost::variant (they support the visitor pattern) or boost::tuple
What you are trying to do sounds a little weird. Normally, you would have a container be a collection of abstract types or objects or functions with the same signature. Otherwise, how would you know how to call the function when you are iterating the container? I like to make the container a collection of function objects with a known signature, then use Boost.Bind to store closures that call the function with additional arguments.
For example:
typedef boost::function<void, void> Function;
typedef std::map<std::string, Function> Functions;
Functions functions:
void foo()
{
...
}
functions["foo"] = foo;
void bar(std::string &s)
{
...
}
// binds the value "hello" to the s parameter
functions["bar"] = boost::bind(bar, "hello");
read this link below. It talks about using boost::bind to store the function pointers in std::map
http://www.gamedev.net/community/forums/topic.asp?topic_id=526381&whichpage=1&#3411515
store interfaces:
struct IStringData
{
virtual std::string get() const = 0;
virtual ~IStringData() {}
};
and make implementaions, one will just hold string value, other implementation will store functor, maybe you will have other implementations in future.
No. You can't. Since boost::function isn't polymorphic, it breaks down there. (It takes a fixed set of argument types.)
There was talk about work in that direction on the boost mail-list, though, so search the archives and see if there is some code you could youse.
A workaround would be to use boost::function but then you need to add to the map not your real functions (i.e. func1/func2) but dispatch functions that extracts the type from the any-container and calls the real function. (And bails if it's wrong, just as in any dynamic langugage.)