BOOST_FOREACH with ptr_vector of noncopyable object - boost-foreach

I have the following:
class X : public boost::noncopyable
{...};
class Y
{
public:
const boost::ptr_vector<X>& getXs() const;
private:
boost::ptr_vector<X> m_xs;
}
int main()
{
Y y1;
//...
const boost::ptr_vector<X>& mx = y1.getXx();
BOOST_FOREACH(boost::ptr_vector<X>::value_type x, mx)
{
// do something with x!
}
}
It compiles but it doesn't link! It says that implicit default copy constructor for X is needed by the BOOST_FOREACH.
How can I iterate over the pointers to X only... no copy contructor, using BOOST_FOREACH.
Thanks.

Try using references in BOOST_FOREACH(), .i.e.
BOOST_FOREACH(boost::ptr_vector<X>::value_type &x, mx)
{
// do something with x!
}

Related

Using a lambda in place of an index-able template parameter

I have a method that takes an index-able object as a template parameter, something like:
template <typename OBJ>
int foo(int n, OBJ o)
{
int x = 0;
for (int i = 0; i < n; ++i) {
x += o[i];
}
return x;
}
Is there a way I can pass a lambda function in for the o parameter? In other words, having the lambda be call-able via the [] operator rather than the () operator?
template<class F>
struct square_bracket_invoke_t {
F f;
template<class T>
auto operator[](T&& t)const
-> typename std::result_of< F const&(T&&) >::type
{ return f(std::forward<T>(t)); }
};
template<class F>
square_bracket_invoke_t< typename std::decay<F>::type >
make_square_bracket_invoke( F&& f ) {
return {std::forward<F>(f)};
}
Live example.
Code is C++11 and has basically zero overhead.
int main() {
std::cout << foo( 6, make_square_bracket_invoke([](int x){ return x; } ) ) << "\n";
}
result is 0+1+2+3+4+5 aka 15.
Is this a good idea? Maybe. But why stop there?
For max amusement:
const auto idx_is = make_square_bracket_invoke([](auto&&f){return make_square_bracket_invoke(decltype(f)(f));});
int main() {
std::cout << foo( 6, idx_is[[](int x){ return x; }] ) << "\n";
}
You can do that by:
Creating a class template, a functor, that has the operator[] defined.
Implementing the operator[] in terms of the operator() of a std::function.
Storing the lambda in a wrapped std::function as a member variable of the class template.
Here's a demonstrative program.
#include <iostream>
#include <functional>
template <typename OBJ>
int foo(int n, OBJ o)
{
int x = 0;
for (int i = 0; i < n; ++i) {
x += o[i];
}
return x;
}
template <typename> struct Functor;
template <typename R> struct Functor<R(int)>
{
using ftype = std::function<R(int)>;
Functor(ftype f) : f_(f) {}
R operator[](int i) const { return f_(i); }
ftype f_;
};
int main()
{
Functor<int(int)> f = {[](int i) -> int {return i*i;}};
std::cout << foo(10, f) << std::endl;
}
and its output
285
Live demo
PS
Functor is not the appropriate name here. It does not overload the function call operator. I suspect there is a more appropriate name.
Well, if it helps, here's a way to forward a wrapper class's operator[] to your lambda's operator().
template<class F>
struct SubscriptWrapper_t {
F f_;
template<class T> auto operator[](T const& t_) const -> decltype(f_(t_)) {
return f_(t_);
}
};
template<class F>
SubscriptWrapper_t<typename std::decay<F>::type> SubscriptWrapper(F&& f_) {
return{std::forward<F>(f_)};
}
I use wrappers like this a lot. They're convenient, and they don't seem to have any computational overhead, at least when compiled by GCC. You can make one for at or even make one for find.
EDIT: Updated for C++11 (and updated to be able to return a reference)
A sketch of a wrapper type that would do this.
template<typename UnaryFunction>
class index_wrapper
{
public:
index_wrapper(UnaryFunction func) : func(std::move(func)) {}
template<typename T>
std::invoke_result_t<UnaryFunction, T> operator[](T&& t)
{ return func(std::forward<T>(t)); }
private:
UnaryFunction func;
};
With usage
#include <iostream>
template <typename OBJ>
int foo(int n, OBJ o)
{
int x = 0;
for (int i = 0; i < n; ++i) {
x += o[i];
}
return x;
}
int main()
{
index_wrapper f([](int i) -> int { return i*i; });
std::cout << foo(10, f) << std::endl;
}
You might want to restrict it to a single parameter type, so that you can provide member type aliases similar to std::vector::reference et.al.

No match for operator+ , and no match for vector construction call in c++

I am trying to implement Matrix Addition using expression templates. I am facing some trouble. Here is my matrix code:
#include<iostream>
#include<vector>
#include<cassert>
template <typename T>
class MatrixExpression {
public:
double operator[](size_t i) const { return static_cast<T const&>(*this)[i];}
size_t size()const { return static_cast<T const&>(*this).size(); }
};
template<typename T>
class Matrix:public MatrixExpression<Matrix<T>>
{
std::vector<std::vector<T>> mat;
public:
Matrix(std::size_t m, std::size_t n):mat(m,std::vector<T>(n)){}
class Proxy
{
std::vector<T> vec;
public:
Proxy(std::vector<T> vec):vec(vec){ }
T operator[](std::size_t i){ return vec[i];}
//T &operator[](std::size_t i){ return vec[i];}
std::size_t size() const{ return vec.size(); }
};
Proxy operator[](std::size_t i) const { return Proxy(mat[i]); }
//Proxy &operator[](std::size_t i) { return Proxy(mat[i]); }
size_t size() const { return mat.size(); }
Matrix(std::initializer_list<std::initializer_list<T>> lst)
{
int m=0,n=0;
for(auto l:lst )
{
for(auto v:l)
{
n++;
}
m++;
}
int i=0,j=0;
mat(m,std::vector<T>(n));
for(auto l:lst )
{
for(auto v:l)
{
mat[i].push_back(v);
}
i++;
}
}
Matrix(MatrixExpression<T> const& matx):mat(matx.size(),std::vector<T>(matx[0].size))
{
for(int i=0;i<matx.size();i++)
{
for(int j=0;j<matx[0].size();j++)
{
mat[i][j] = matx[i][j];
}
}
}
};
template<typename T, typename X, typename Y>
class MatrixSum:public MatrixExpression<MatrixSum<T,X,Y>>
{
X const& x;
Y const& y;
public:
MatrixSum(X const& x1, Y const& y1):x(x1),y(y1){
assert(x1.size()==y1.size());
assert(x1[0].size()==y1[0].size());
}
class ProxySum
{
std::vector<T> vec1,vec2;
public:
ProxySum(std::vector<T> vec1,std::vector<T> vec2):vec1(vec1),vec2(vec2){ }
T operator[](std::size_t i){ return vec1[i] + vec2[i];}
//T &operator[](std::size_t i){ return vec1[i] + vec2[i];}
std::size_t size() const{ return vec1[0].size(); }
};
ProxySum operator[](std::size_t i) const { return ProxySum(x[i],y[i]); }
//ProxySum &operator[](std::size_t i){ return ProxySum(x[i],y[i]); }
size_t size() const { return x.size(); }
};
template<typename T,typename X,typename Y>
MatrixSum<T,X,Y>
operator+(X const& x, Y const& y)
{
return MatrixSum<T,X,Y>(x,y);
}
I am getting two errors when using the Matrix class. First is the operator+ does not exist for Matrix (I used int from testing) even though I have implemented operator overloading for '+', and another error is in the second constructor for Matrix. It says that the call I have made for the constructor of mat variable is invalid.But vectors do have such constructor
1) The following line is not a valid C++ syntax:
mat(m,std::vector<T>(n));
You should initialize mat member object in the constructor's initialization list, like this (assuming the outermost initializer_list is not empty):
Matrix(std::initializer_list<std::initializer_list<T>> lst) : mat(lst.size(), std::vector<T>(begin(lst)->size()))
2) As for the operator + you provided:
template<typename T,typename X,typename Y>
MatrixSum<T,X,Y>
operator+(X const& x, Y const& y)
{
return MatrixSum<T,X,Y>(x,y);
}
Note that T template parameter is non-deducible, so the compiler cannot figure it out and thus cannot use this operator. The only way to call it would be like this:
matrix1.operator +<some_type>(matrix2);
...which is probably not what you want.
The right way would be to try and compute T at compile-time, based on X and Y types, using some metaprogramming.

Hash table of templated functor

I want to create a hastable to member templated functor, I explain.
Here is my exemple which does'nt work:
#include <iostream>
#include <unordered_map>
using namespace std;
class MyFirstClass
{
int i_;
public:
MyFirstClass(): i_(0) {}
void setI(int i) { i_ = i; }
int getI() { return i_; }
};
class MySecondClass
{
bool b_;
public:
MySecondClass(): b_(0) {}
void setB(bool b) { b_ = b; }
bool getB() { return b_; }
};
template<class X, void (X::*p)()>
class MyFunctor
{
X& _x;
public:
MyFunctor(X& x) : _x( x ) {}
void operator()() const { (_x.*p)(); }
};
int main(int argc, char *argv[])
{
unordered_map<string,MyFunctor> myHashTable;
MyFirstClass first;
MyFirstClass second;
myHashTable["int"] = first::setI;
myHashTable["bool"] = second::setB;
//
string key = "bool";
int value = 1;
myHashTable[key](value);
return 0;
}
I have multiple class with their own setter . I would like to be able thanks to the has table and a command {string,int} change the value of the corresponding class.
The previous code is not working for the moment and I am stuck.
There are a few problems with your code, as it stands.
Firstly, from your example unordered_map<string,MyFunctor> doesn't name a type, because MyFunctor doesn't name a type. You could create a non-template base class with a virtual operator(), and then have MyFunctor inherit from it.
Second, you aren't using compatible method pointers, MyFirstClass::setI and MySecondClass::setB both take a parameter.
Third, related to the first, you have to specify the template parameters when constructing an object from a class template. (until c++17's class template deduction guides). You also have ungrammatical syntax that I assume is trying to specify the object argument to the MyFunctor constructor alongside the method-pointer template argument.
You would have something like
class MyFunctorBase {
virtual void operator()(void * i) const = 0;
}
template<class T, class X, void (X::*p)(T)>
class MyFunctor : public MyFunctorBase
{
X& _x;
public:
MyFunctor(X& x) : _x( x ) {}
void operator()(void * i) const override { (_x.*p)(*static_cast<T*>(i)); }
};
int main(int argc, char *argv[])
{
unordered_map<string,shared_ptr<MyFunctorBase>> myHashTable;
MyFirstClass first;
MyFirstClass second;
myHashTable["int"] = make_shared<MyFunctor<int, MyFirstClass, &MyFirstClass::setI>>(first);
myHashTable["bool"] = make_shared<MyFunctor<bool, MySecondClass, &MySecondClass::setB>>(second);
//
string key = "bool";
bool value = true;
(*myHashTable[key])(static_cast<void *>(&value));
return 0;
}
Or, much more easily, use the existing std::function, which does that for you
int main(int argc, char *argv[])
{
unordered_map<string,function<void(void *)>> myHashTable;
MyFirstClass first;
MyFirstClass second;
myHashTable["int"] = [first](void * i) { first.setI(*static_cast<int *>(i)); };
myHashTable["bool"] = [second](void * i) { second.setB(*static_cast<bool *>(i)); };
//
string key = "bool";
bool value = true;
myHashTable[key](static_cast<void *>(&value));
return 0;
}

Issue when trying to call a template base class constructor using braced-init-list

New student to c++ so forgive me if I mix up my terminology. Been reading Stroustrup and hes very adamant about using the braced-init-list syntax to to construct and initialize objects which I've been trying to apply in my studies. However I encountered some weird behavior when exploring inheritance with templates and I've been unable to find an answer online so far. Here are a couple of examples:
non template example:
class A {
int x;
public:
A(int x = 0) : x{ x } {}; // works as expected.
};
class B : public A {
int y;
public:
B(int x = 1, int y = 1) : A(x), y{ y } {}; // old syntax works obviously.
};
template example which fails to compile with the error below:
template<typename T>
class A {
T x;
public:
A(T x = 0) : x{ x } {}; // works as expected.
};
template<typename T>
class B : public A<T> {
T y;
public:
// Compilation fails on the following line (vs2015).
// Compiler has an issue with A<T>{ X }. Replacing {} with ()
// works as expected. Shouldn't it work with {} as well?
// B(T x = 1, T y = 1) : A<T>( x ), y{ y } {};
B(T x = 1, T y = 1) : A<T>{ x }, y{ y } {};
};
error:
Error C2059 syntax error: ','
Error C2334 unexpected token(s) preceding '{'; skipping apparent function body
now what really baffles me is why the following works:
template<typename T>
class C : public A<T> {
using A_alias = A<T>;
T z;
public:
// Why does this workaround work while the expected syntax fails
// to compile?
C(T x = 2, T z = 2) : A_alias{ x }, z{ z } {};
};
Can anyone please shed some light on whats going on here, I've been going over the book all the day and I cant find any reference to this and searching has been fruitless so far since I'm not sure exactly what to search for.
This looks like a compiler bug. gcc compiles the code in question without a problem, at the --std=c++14 level.

Segmentation fault in boost::odeint my_vector.cpp example

I am trying to test the my_vector.cpp program from boost::odeint examples but without any success. I get Segmentation Fault when I run the program.
Compilation: g++ -std=c++14 -o my_vector my_vector.cpp
It runs with std::vector<> instead of my_vector for the state_type. I suspect there is something wrong with is_resizable but I don't know how to fix it.
Here is the code for my_vector.cpp which you can get from github
/*
* Copyright 2011-2012 Mario Mulansky
* Copyright 2012-2013 Karsten Ahnert
*
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or
* copy at http://www.boost.org/LICENSE_1_0.txt)
*
* Example for self defined vector type.
*/
#include <vector>
#include <boost/numeric/odeint.hpp>
//[my_vector
template< int MAX_N >
class my_vector
{
typedef std::vector< double > vector;
public:
typedef vector::iterator iterator;
typedef vector::const_iterator const_iterator;
public:
my_vector( const size_t N )
: m_v( N )
{
m_v.reserve( MAX_N );
}
my_vector()
: m_v()
{
m_v.reserve( MAX_N );
}
// ... [ implement container interface ]
//]
const double & operator[]( const size_t n ) const
{ return m_v[n]; }
double & operator[]( const size_t n )
{ return m_v[n]; }
iterator begin()
{ return m_v.begin(); }
const_iterator begin() const
{ return m_v.begin(); }
iterator end()
{ return m_v.end(); }
const_iterator end() const
{ return m_v.end(); }
size_t size() const
{ return m_v.size(); }
void resize( const size_t n )
{ m_v.resize( n ); }
private:
std::vector< double > m_v;
};
//[my_vector_resizeable
// define my_vector as resizeable
namespace boost { namespace numeric { namespace odeint {
template<size_t N>
struct is_resizeable< my_vector<N> >
{
typedef boost::true_type type;
static const bool value = type::value;
};
} } }
//]
typedef my_vector<3> state_type;
void lorenz( const state_type &x , state_type &dxdt , const double t )
{
const double sigma( 10.0 );
const double R( 28.0 );
const double b( 8.0 / 3.0 );
dxdt[0] = sigma * ( x[1] - x[0] );
dxdt[1] = R * x[0] - x[1] - x[0] * x[2];
dxdt[2] = -b * x[2] + x[0] * x[1];
}
using namespace boost::numeric::odeint;
int main()
{
state_type x(3);
x[0] = 5.0 ; x[1] = 10.0 ; x[2] = 10.0;
// my_vector works with range_algebra as it implements
// the required parts of a container interface
// no further work is required
integrate_const( runge_kutta4< state_type >() , lorenz , x , 0.0 , 10.0 , 0.1 );
}
I can reproduce this with g++-4.8.
I've opened an issue on this at the odeint github repository:
https://github.com/headmyshoulder/odeint-v2/issues/180
edit:
I've found the problem and solved it: https://github.com/headmyshoulder/odeint-v2/commit/965a8e456d5e9dff47f0121a4d12aac8c845ea5e
The problem was an inconsistent template parameter type that prevented the is_resizeable definition to work properly, as expected by the op already.
changing the my_ vector template parameter type to size_t fixes this:
template<size_t N>
class my_vector

Resources