How to initialize a sequence of non-movable, non-copyable objects? - c++

Let's say I have a type which is neither movable nor copyable:
struct foo
{
explicit foo( size_t ){}
~foo(){}
foo( foo const & ) = delete;
foo( foo && ) = delete;
foo& operator=( foo const & ) = delete;
foo& operator=( foo & ) = delete;
};
Now given a number known at compile time (call it N), is there any way that I can create a "sequence" of these on the stack with each one initialized with numbers 0 through N-1? I would be satisfied with a C-style array foo[N], a std::array< foo, N >, or perhaps even a std::tuple of some kind.
What I'm trying to avoid is writing out:
foo f0( 0 ), f1( 1 ), ... fNminus1( N-1 );
when it feels like this is something the compiler should be able to do for me. The best I've been able to come up with is using boost::optional.
boost::optional< foo > f[N];
for( size_t i = 0U; i < N; ++i )
f[i] = boost::in_place( i );
But that relies on runtime logic even though all the required information is available at compile-time. Plus, I'm left with something that behaves like an array of pointers.

// create a type with the proper alignment
typedef std::aligned_storage<sizeof(foo), std::alignment_of<foo>::value>::type buffer_type;
const int N = 10;
// create an array of uninitialized raw data
buffer_type storage_buffer[N];
// initialize each foo object with placement new
for (size_t i=0; i<N; ++i)
new (storage_buffer + i) foo(i);
foo * fp = (foo*)(&storage_buffer);
// access your foo objects via fp
// you must manually call the destructor of each object
for (size_t i=0; i<N; ++i)
fp[i].~foo();
If that seems like a lot of hassle, it is. But you could easily encapsulate that functionality in a class.

Although not strictly an array, you can sort of accomplish this with template recursion
template< typename T, size_t N >
struct type_array : public type_array< T, N-1 > {
// this is the Nth element
T elem;
// it is constructed with N
type_array() : elem( N ) {}
// member function to return the Nth element
T & get( size_t n ) {
if ( n == N ) {
return elem;
} else {
return type_array< T, N-1 >::get( n );
}
}
};
// base case when N == 0
template< typename T >
struct type_array<T, 0> {
T elem;
type_array() : elem( 0 ) {}
T & get( size_t n ) {
return elem;
}
};
Usage:
type_array< foo, 100 > foo_array; // construct 100 foos
foo_array.get(1); // foo with n == 1
foo_array.get(2); // foo with n == 2

Like the answer from Benjamin Lindley, but packed in a class:
#include <type_traits>
#include <utility>
#include <new>
template<typename T>
class uninitialized {
public:
constexpr uninitialized() { }
~uninitialized() {
get().~T();
}
explicit uninitialized(const uninitialized& other) {
construct(other);
}
explicit uninitialized(uninitialized&& other) {
construct(std::move(other));
}
template<class... Args>
explicit uninitialized(Args&&... args) {
construct(std::forward<Args>(args)...);
}
template<class... Args>
void construct(Args&&... args) noexcept {
static_assert(std::is_nothrow_constructible<T, Args...>::value, "constructor should not throw!");
::new(getPointer()) T (std::forward<Args>(args)...);
}
uninitialized& operator = (const T& t) {
get() = t;
return *this;
}
uninitialized& operator = (T&& t) {
get() = std::move(t);
return *this;
}
T* operator -> () { return getPointer(); }
T& operator * () { return get(); }
T* operator & () { return getPointer(); }
T* getPointer() { return reinterpret_cast<T*>(&data); }
T& get() { return *reinterpret_cast<T*>(&data); }
const T* operator -> () const { return getPointer(); }
const T& operator * () const { return get(); }
const T* operator & () const { return getPointer(); }
const T* getPointer() const { return reinterpret_cast<const T*>(&data); }
const T& get() const { return *reinterpret_cast<const T*>(&data); }
private:
std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type data;
};
Now things are a little bit easier:
uninitialized<foo> f[N];
for (size_t i = 0; i < N; ++i)
f[i].construct(i);
for (const auto& fooref : f)
fooref->bar();
// foo::~foo is called for you

Related

Is it possible to get rid of template specialisation to stop recursion?

I'm writing my own container class that also provides iterators. These iterators can be dereferenced and reveal then a sub-range of the original container, for which again an iterator can be obtained.
Currently, I've a template iterator class (using boost::iterator_facade) that dereferences to an Collection ("range") if L!=0 or to a T& (stored elements) if L==0. Is it possible combine both in one class, such that less duplicate code is needed?
template<typename T, int L>
class CollectionIter : public boost::iterator_facade<
CollectionIter<T,L>, // type it selfe
Collection<T,L-1>, // value type
boost::random_access_traversal_tag,
Collection<T,L-1> > // deref. type
{
public:
CollectionIter(T* ptr, const std::vector<int>& collectionSize_)
: pointer(ptr), collectionSize(collectionSize_) { }
T* element() { return pointer; }
private:
friend class boost::iterator_core_access;
bool equal(const CollectionIter<T,L>& other) const { return pointer==other.pointer; }
auto dereference() const { return Collection<T,L-1>(pointer, collectionSize); }
void increment() { pointer = pointer + stepsize(); }
void decrement() { pointer = pointer - stepsize(); }
void advance(size_t i) { pointer = pointer + i*stepsize(); }
auto distance_to(const CollectionIter<T,L>& other) { return (other.pointer - pointer)/stepsize(); }
int stepsize() { return collectionSize.at(L); }
T* pointer;
const std::vector<int>& collectionSize;
};
/* Groundlevel Collection: deref returns T& */
template<typename T>
class CollectionIter<T,0> : public boost::iterator_facade<
CollectionIter<T,0>,
T,
boost::random_access_traversal_tag >
{
public:
CollectionIter(T* ptr, const std::vector<int>& collectionSize_)
: pointer(ptr), collectionSize(collectionSize_) { assert(stepsize()==1); }
T* element() { return pointer; }
private:
friend class boost::iterator_core_access;
bool equal(const CollectionIter<T,0>& other) const { return pointer==other.pointer; }
T& dereference() const { return *pointer; }
void increment() { pointer = pointer + stepsize(); }
void decrement() { pointer = pointer - stepsize(); }
void advance(size_t i) { pointer = pointer + i*stepsize(); }
auto distance_to(const CollectionIter<T,0>& other) { return (other.pointer - pointer)/stepsize(); }
int stepsize() { return collectionSize.at(0); }
T* pointer;
const std::vector<int>& collectionSize;
};
I see only three differences in the two version of CollectionIter:
(1) the boost::iterator_facade() inherited class receive different arguments. You can solve this with std::conditional as suggested by Johannes Schaub; something like
public std::conditional< (L > 0U),
boost::iterator_facade<
CollectionIter<T, L>,
Collection<T, L-1U>,
boost::random_access_traversal_tag,
Collection<T, L-1U> >,
boost::iterator_facade<
CollectionIter<T, 0U>,
T,
boost::random_access_traversal_tag > >
(2) the assert(stepsize()==1); in the constructor is present only in the ground (L == 0U) version. You can modify it as
assert( (L > 0U) || (stepsize() == 1) );
(3) the recursive dereference() method is really different in the ground version. I'm not an expert of SFINAE but, if I'm not wrong, you can insert both as follows
template <int M = L, typename = std::enable_if_t<(M > 0U)>>
auto dereference () const
{ return Collection<T, L-1U>(pointer, collectionSize); }
template <int M = L, typename = std::enable_if_t<(M == 0U)>>
T & dereference () const
{ return *pointer; }
So the full class become (sorry: I've changed L in a std::size_t)
template <typename T, std::size_t L>
class CollectionIter :
public std::conditional< (L > 0U),
boost::iterator_facade<
CollectionIter<T, L>,
Collection<T, L-1U>,
boost::random_access_traversal_tag,
Collection<T, L-1U> >,
boost::iterator_facade<
CollectionIter<T, 0U>,
T,
boost::random_access_traversal_tag > >
{
public:
CollectionIter (T * ptr, const std::vector<int> & collectionSize_)
: pointer(ptr), collectionSize(collectionSize_)
{ assert( (L > 0U) || (stepsize() == 1) ); }
T* element() { return pointer; }
private:
friend class boost::iterator_core_access;
bool equal (const CollectionIter<T, L> & other) const
{ return pointer==other.pointer; }
template <int M = L, typename = std::enable_if_t<(M > 0U)>>
auto dereference () const
{ return Collection<T, L-1U>(pointer, collectionSize); }
template <int M = L, typename = std::enable_if_t<(M == 0U)>>
T & dereference () const
{ return *pointer; }
void increment ()
{ pointer = pointer + stepsize(); }
void decrement()
{ pointer = pointer - stepsize(); }
void advance (size_t i)
{ pointer = pointer + i*stepsize(); }
auto distance_to (const CollectionIter<T, L> & other)
{ return (other.pointer - pointer)/stepsize(); }
int stepsize()
{ return collectionSize.at(L); }
T * pointer;
const std::vector<int> & collectionSize;
};

How to make_shared count times, with different areas allocated without recur to a loop?

How to make_shared count times, with different areas allocated without recur to a loop?
I have the following code:
for( unsigned int count = 0; count < demandedSize; ++count )
{
m_connectionList.push_back( std::make_shared< Foo >( m_ip, m_port ));
}
How to shorten this without a loop?
I know std::vector receaves a second argument as const T&, but in that case all shared_ptrs points to the same address (value is copied).
std::vector< std::shared_ptr<Foo> > vet( demandedSize, std::make_shared<Foo>( m_ip, m_port ) );
How to execute make_shared count times, with different areas allocated as result without recur to a loop
This should do the trick:
std::generate_n( back_inserter( m_connectionList ), demandedSize, [this]{
return std::make_shared< Foo >( m_ip, m_port ) );
});
Live Example on Coliru.
template<class X>
struct arrow_helper_t {
X x;
auto operator->()&& { return std::addressof(x); }
};
template<class X>
arrow_helper_t<X> arrow_helper(X&& x){ return {std::forward<X>(x)}; }
template<class F>
struct generator_iterator_t {
std::size_t i = 0;
F f;
generator_iterator_t()=default;
generator_iterator_t(generator_iterator_t const&)=default;
generator_iterator_t(generator_iterator_t &&)=default;
generator_iterator_t& operator=(generator_iterator_t const&)=default;
generator_iterator_t& operator=(generator_iterator_t &&)=default;
using iterator_category = std::input_iterator_tag;
using reference=decltype(std::declval<F const&>()(std::declval<std::size_t const&>()));
using value_type = std::decay_t<reference>;
using pointer = arrow_helper_t<reference>;
using difference_type = std::ptrdiff_t;
using self_t = generator_iterator_t;
friend bool operator!=(self_t const& lhs, self_t const& rhs) { return lhs.i != rhs.i; }
friend bool operator==(self_t const& lhs, self_t const& rhs) { return lhs.i == rhs.i; }
decltype(auto) operator*()const { return f(i); }
auto operator->() const { return arrow_helper(**this); }
self_t& operator++() { ++i; return *this; }
self_t operator++(int) { auto r = *this; ++i; return r; }
};
template<class F>
generator_iterator_t<F>
generator_iterator( F f, std::size_t i ) {
return {i, std::move(f)};
}
template<class F>
auto generator_range( F f, std::size_t i ) {
return std::make_pair(
generator_iterator(f, 0),
generator_iterator(f, i)
);
}
auto range = generator_range([&](auto){return std::make_shared< Foo >( m_ip, m_port );}, demandedSize);
m_connectionList.reserve( m_connectionList.size()+demandedSize );
m_connectionList.insert(m_connectionList.end(),
range.first, range.second
);
or somesuch. boost probably does it better.
live example.

View class into a container

I'm trying to write a class View to serve as a view into another container, (a sparse matrix class, but that should be unimportant for the question).
View should contain references (e.g. std::reference_wrapper) to a selection of elements in the container, and have methods returning references to those elements, as well as an assignment operator making one block equal to another.
My problem is that I want View to be able to take values in addition to references: both be constructed from values as a non-reference instance to be used in assignments, and assign values to single elements in a reference instance.
An MVE of the code so far is:
#include <array>
template<typename T, size_t size>
class View
{
private:
std::array<T, size> _values;
public:
View(const std::array<T, size> & values)
: _values{ values } { }
// ----------
View<T, size> & operator=(const View<T, size> & other)
{
for ( size_t i = 0; i < size; ++i ) {
this->get(i) = other.get(i);
}
return *this;
}
// ----------
T & get(size_t idx)
{
return _values.at(idx);
}
const T & get(size_t idx) const
{
return _values.at(idx);
}
};
It can be used like this:
#include <functional>
#include <iostream>
int main()
{
int values[5] = { 1, 2, 3, 4, 5 };
View<int, 2> v1{
{values[0], values[1]}
};
View<std::reference_wrapper<int>, 2> v2{
{values[3], values[4]}
};
// WHAT WORKS
v1.get(0) = 10; // can assign to the non reference `View<int, size>`,
// works as intended
v2.get(0) += 9; // can increment through the reference wrappers,
// this also works as intended
// WHAT THAT DOES NOT WORK
// v2 = v1; // nether of these work, as there is no conversion
// v1 = v2; // between `View<std::reference_wrapper<int>, size>`
// and `View<int, size>`. It is the first expression
// that is of most interest
// v2.get(1) = 10; // this doesn't work as the return is a
// `std::reference_wrapper<int>`, not a
// reference to an `int`
v2.get(1).get() = 10; // this works as a work-around to
// this problem, but it feels clunky, and it
// makes the interface between the two types
// different
for ( size_t i = 0; i < 2; ++i ) {
std::cout << v1.get(i) << " ";
}
std::cout << std::endl;
for ( size_t i = 0; i < 5; ++i ) {
std::cout << values[i] << " ";
}
std::cout << std::endl;
}
This should output:
10 2
1 2 3 13 10
I'm using clang++ to compile on Ubuntu 15.10.
So specifically,
How should I implement the assignment operator to allow View<T, size> and View<std::reference_wrapper<T>, size> to be assigned to each other (or at least the former to be assigned to latter). Creating two versions
View<T, size> & operator=(const View<T, size> & other);
View<T, size> & operator=(
const View<std::reference_wrapper<T>, size> & other);
does not work, (as a View<std::reference_wrapper<T>, size> then would need a View<std::reference_wrapper<std::reference_wrapper<T> >, size> for the second overload).
How can I write the get(size_t idx) methods such that the return is T & for bothView<T, size> and View<std::reference_wrapper<T>, size>?
I have a feeling this can be accomplished by using templates somehow, but I'm still quite new to template programming so I'm a bit lost.
Here is a way to make get() return T& for T and std::reference_wrapper<T>:
template <typename T>
struct get_value_type {
using type = T;
};
template <typename T>
struct get_value_type<std::reference_wrapper<T>> {
using type = T;
};
template<typename T, size_t size>
class View {
using value_type = typename get_value_type<T>::type;
value_type & get(size_t idx) {
return _values.at(idx);
}
const value_type & get(size_t idx) const {
return _values.at(idx);
}
};
The get_value_type template help us obtain T from both T and std::reference_wrapper<T>, then you simply change the return type of get() to value_type, and since std::reference_wrapper<T> is implicitly convertible to T& it works.
Now that you have access to value_type, you can use it to create your two operator=:
View& operator= (const View<value_type, size> & other) {
for (size_t i = 0; i < size; ++i) {
this->get(i) = other.get(i);
}
return *this;
}
View& operator=(const View<std::reference_wrapper<value_type>, size> & other) {
for (size_t i = 0; i < size; ++i) {
this->get(i) = other.get(i);
}
return *this;
}
In case you want to allow assignment from different view (e.g. a view of int to a view of double), you could use a templated version:
template <typename U>
View<T, size> & operator=(const View<U, size> & other) {
for (size_t i = 0; i < size; ++i) {
this->get(i) = other.get(i);
}
return *this;
}
A small addition that may be a bit off-topic but instead of having an std::array attribute, you could inherit from std::array like the following:
template<typename T, size_t Size>
struct View: public std::array<T, Size> {
using array_type = std::array<T, Size>;
using value_type = typename get_value_type<T>::type;
View (std::array<T, Size> const& values) : array_type (values) { }
View& operator=(const View<value_type, Size> & other) {
for (size_t i = 0; i < Size; ++i) {
(*this)[i] = other[i];
}
return *this;
}
View& operator=(const View<std::reference_wrapper<value_type>, Size> & other) {
for (size_t i = 0; i < Size; ++i) {
(*this)[i] = other[i];
}
return *this;
}
value_type & operator[](size_t idx) {
return array_type::operator[](idx);
}
const value_type & operator[](size_t idx) const {
return array_type::operator[](idx);
}
};
This would allow you to use a lot of stuff from the standard library on your View without having to redefine anything.

Unclear C++ syntax in operator overloading

I'm still new to c++ and trying to understand the Expression Templates. I came across an example code on Wikipedia. I Understood most of the program and how it works but I'm not clear how these lines are interpreted by compiler:
operator A&() { return static_cast< A&>(*this); }
operator A const&() const { return static_cast<const A&>(*this); }
from the base expression template class below.
Usually the syntax of operator overloading is return_datatype operator+ (args){body} (e.g for + operator) but this gives errors and the ones in the function compiles without any error. Can anybody explain these two lines? What does A& and A const& before the operators do? And why A& operator() (){} and A const& operator() (){} doesn't work? It gives error:
no matching function for call to 'Vec::Vec(const Expr<Vec>&)'
ExprSum(const Expr<A>& a, const Expr<B>& b): _u(a), _v(b) {}
-Pranav
The complete code:
#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
template <class A>
class Expr{
public:
typedef std::vector<double> container_type;
typedef typename container_type::size_type size_type;
typedef typename container_type::value_type value_type;
typedef typename container_type::reference reference;
size_type size() const {return static_cast<A const&>(*this).size(); }
value_type operator [] (size_t i) const {return static_cast<A const&> (*this)[i];}
operator A&() { return static_cast< A&>(*this); }
operator A const&() const { return static_cast<const A&>(*this); }
};
class Vec : public Expr<Vec> {
private:
container_type x;
public:
Vec(){}
Vec(size_type length) :x(length) {}
size_type size() const { return x.size(); }
reference operator [] (size_type i){
assert(i < x.size());
return x[i];
}
value_type operator [] (size_type i) const {
assert(i < x.size());
return x[i];
}
template <class A>
void operator = (const Expr<A>& ea){
x.resize(ea.size());
for(size_t i = 0; i < x.size(); i++){
x[i] = ea[i];
}
}
};
template <class A, class B>
class ExprSum : public Expr <ExprSum <A,B> >{
private:
A _u;
B _v;
public:
typedef Vec::size_type size_type;
typedef Vec::value_type value_type;
ExprSum(const Expr<A>& a, const Expr<B>& b): _u(a), _v(b) {}
value_type operator [] (size_t i) const { return (_u[i] + _v[i]); }
size_type size() const { return _u.size(); }
};
template <class A, class B>
ExprSum <A,B> const operator + (Expr<A> const& u, Expr<B> const& v){
return ExprSum <A,B> (u,v);
}
int main(){
size_t n = 10;
Vec x(n);
Vec y(n);
Vec z;
for(size_t i = 0; i < n; i++){
x[i] = i;
y[i] = 2*i;
}
z = x + y;
cout << z[7] << endl;
cout << "Hello world!" << endl;
return 0;
}
This is a conversion operator. It looks similar to a normal overloaded operator, but it doesn't have a specified return type, and in place of the operator symbol you have the conversion target type.

Simulating nullptr & nullptr_t for GCC 4.5.3

Due to some legacy reasons I'm stuck with MIPS-GCC 4.5.3. But the code which I'm trying to compile uses C++11 nullptr & nullptr_t heavily which is a missing feature in GCC 4.5.3.
After some googling & getting into the usage I ended up creating a nullptr wrapper like below, but unfortunately it doesn't satisfy some of the use case,
namespace std {
class nullptr_t {
public:
nullptr_t() { }
template <typename T> nullptr_t(const T&) { }
template <class T> nullptr_t(const T*) { }
template <class T> nullptr_t(T*) { }
template <typename T, typename U> nullptr_t(const typename T::U*) { }
template<typename T> operator T*() { return 0;}
template<typename T1, typename T2> operator T1 T2::*() { return 0; }
operator int() const { return 0; }
operator unsigned() const { return 0; }
operator bool() const { return false; }
bool operator == (unsigned i) const { return i == 0; }
bool operator != (unsigned i) const { return i != 0; }
bool operator !() const { return true; }
} nullptr = {};
}
using std::nullptr;
template<typename T> struct DummyContainer {
DummyContainer(T* ptr)
: m_ptr(ptr) { }
DummyContainer(std::nullptr_t)
: m_ptr(0) { }
T& operator = (std::nullptr_t) { return *m_ptr; }
private: T* m_ptr;
};
int main(int argc, char** argv)
{
const char* case1 = nullptr; // working
// I think for below case std::unique_ptr has to be modified to take std::nullptr_t during construction & operator =
std::unique_ptr<char> case2 = nullptr; // not working.
DummyContainer<char> case3 = nullptr; // working
case3 = nullptr; //working
unsigned* case4 = argc > 1 ? nullptr : nullptr; //works
unsigned* case5 = argc > 2 ? (unsigned*)0 : nullptr; //not working. (It is the major issue as of now)
return 0;
}
Here the major case is unsigned* case5 = argc > 2 ? (unsigned*)0 : nullptr;
IDEONE snapshot : http://ideone.com/m1mhtB
(Thanks to http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf)
Any tips/suggestions will be appreciated :)
(Note: please avoid answers like upgrade your gcc)
Below solution seems to be working,
Original source: https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/wtf/NullPtr.h
namespace std {
class nullptr_t {
public:
// Required in order to create const nullptr_t objects without an
// explicit initializer in GCC 4.5, a la:
//
// const std::nullptr_t nullptr;
nullptr_t() { }
// Make nullptr convertible to any pointer type.
template<typename T> operator T*() const { return 0; }
// Make nullptr convertible to any member pointer type.
template<typename C, typename T> operator T C::*() { return 0; }
private:
// Do not allow taking the address of nullptr.
void operator&();
};
}
const std::nullptr_t nullptr;
IDEOne: http://ideone.com/Bnp6th