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
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?
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.
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.
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.
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