regarding my Point struct already mentioned here:
template class: ctor against function -> new C++ standard
is there a chance to replace the function toint() with a cast-operator (int)?
namespace point {
template < unsigned int dims, typename T >
struct Point {
T X[ dims ];
//umm???
template < typename U >
Point< dims, U > operator U() const {
Point< dims, U > ret;
std::copy( X, X + dims, ret.X );
return ret;
}
//umm???
Point< dims, int > operator int() const {
Point<dims, int> ret;
std::copy( X, X + dims, ret.X );
return ret;
}
//OK
Point<dims, int> toint() {
Point<dims, int> ret;
std::copy( X, X + dims, ret.X );
return ret;
}
}; //struct Point
template < typename T >
Point< 2, T > Create( T X0, T X1 ) {
Point< 2, T > ret;
ret.X[ 0 ] = X0; ret.X[ 1 ] = X1;
return ret;
}
}; //namespace point
int main(void) {
using namespace point;
Point< 2, double > p2d = point::Create( 12.3, 34.5 );
Point< 2, int > p2i = (int)p2d; //äähhm???
std::cout << p2d.str() << std::endl;
char c; std::cin >> c;
return 0;
}
I think the problem is here that C++ cannot distinguish between different return types? many thanks in advance.
regards
Oops
The correct syntax is
operator int() const {
...
There's no need to have that extra return type when you overload the cast operator.
And when you say (int)x, the compiler really expects to get an int, not a Point<dims, int>. Probably you want a constructor instead.
template <typename U>
Point(const Point<dims, U>& other) { ... }
Related
If I have a std::tuple of statically allocated Eigen::Vectors (from the popular Eigen library), for example
std::tuple<Eigen::Vector2f, Eigen::Vector3f, Eigen::Vector2f>
Is there a way I can turn this into a single Eigen::Vector7f (i.e., Eigen::Matrix<float, 7, 1>) of the three vectors concatenated? It feels like I should be able to do this at compile time, given that the sizes and types of everything are known.
You can write:
template<int R1, int R2, int R3>
auto foo(std::tuple<
Eigen::Matrix<float,R1,1>,
Eigen::Matrix<float,R2,1>,
Eigen::Matrix<float,R3,1> > t)
{
Eigen::Matrix<float,R1+R2+R3,1> res;
res.template block<R1,1>(0,0) = std::get<0>(t);
res.template block<R2,1>(R1,0) = std::get<1>(t);
res.template block<R3,1>(R1+R2,0) = std::get<2>(t);
return res;
}
int main() {
Eigen::Vector2f v1;
v1 << 1,2;
Eigen::Vector3f v2;
v2 << 3,4,5;
std::cout << foo(std::make_tuple(v1,v2,v1)) << std::endl;
as output:
1,2,3,4,5,1,2
Live demo
Below is more generic version taking multiple vectors as tuple components:
template<class RES, int ... R, size_t ... Indices>
void concatenateHelper(RES& res,
const std::tuple< Eigen::Matrix<float,R,1>... >& t,
std::index_sequence<Indices...>)
{
int idx = 0;
int fakeArray [] = {(res.template block<R,1>(idx,0) = std::get<Indices>(t),idx += R,0)...};
static_cast<void>(fakeArray);
}
template<int ... R>
auto concatenate(const std::tuple< Eigen::Matrix<float,R,1> ... >& t)
{
Eigen::Matrix<float, (R + ...),1> res;
concatenateHelper(res,t,std::make_index_sequence<sizeof...(R)>{});
return res;
}
Demo
I am trying to use templates to represent simple polynomials like x^2 + 3x + 5. My idea is to represent them as sum of terms with each term having a coefficient and a power so e.g. x^2 has coeff=1 and power=2. I also want to be able to evaluate the polynomials for some x (they only have 1 unknown but in many places). So far I have:
struct PolyEnd{
double eval(double x){
return 0;
}
};
template <int coeff, int power, class Tail> struct Poly {
typedef Tail tt;
double eval(double x){
double curr = coeff * std::pow(x, power);
return curr; // has to call eval(x) on rest of the terms which are in the tail and return the sum with "curr"
}
};
int main()
{
double x = 2;
Poly<1,1,Poly<1,1,PolyEnd>> poly;
std::cout << poly.eval(x) << std::endl;
return 0;
}
However, I am stuck. Is what I am trying even possible? If so how can I make the recursive eval() calls work?
Yes, you can do that, you just need to call eval on the tail and since all the classes are state-less, you can just create an instance to call the member function on, on the spot:
struct PolyEnd{
double eval(double x){
return 0;
}
};
template <int coeff, int power, class Tail> struct Poly {
typedef Tail tt;
double eval(double x){
double curr = coeff * std::pow(x, power);
return curr + Tail{}.eval(x);
}
};
int main()
{
double x = 2;
Poly<1,1,Poly<1,1,PolyEnd>> poly;
std::cout << poly.eval(x) << std::endl;
return 0;
}
or if you make eval static, then you can call Tail::eval(x) directly.
I guess that you are experimenting with metaprogramming. Your question also made me excited, because i am also newbie in metaprogramming and I want to practise. #walnut's answer already accepted but there is no harm to share another implementation. I used some basic metaprogramming techniques.
I hope it will help you.
#include <cmath>
#include <iostream>
#include <string>
template<int Value>
struct coeff
{ };
template<int Value>
struct power
{ };
template<typename Coefficient, typename Power>
struct term;
template<int Coefficient , int Power>
struct term< coeff<Coefficient> , power<Power> >
{
inline double eval( double x ) const noexcept {
return Coefficient * std::pow( x , Power );
}
};
template<int Value>
using constant = term< coeff<Value> , power<1> >;
template<int Value>
using exponential = term< coeff<1> , power<Value> >;
template<typename... T>
struct polynomial
{
static_assert( sizeof...(T) == 0, "A polynomial can only be expressed in 'term's.");
[[nodiscard]] constexpr double eval( double ) const noexcept {
return 0;
}
[[nodiscard]] std::string to_string() const noexcept {
return std::string{};
}
};
template<int Coefficient, int Power, typename... Tail>
struct polynomial<term< coeff<Coefficient> , power<Power> >, Tail...>
: polynomial<Tail...>
{
[[nodiscard]] constexpr double eval( double x ) const noexcept {
return m_t.eval( x ) + polynomial<Tail...>::eval( x );
}
[[nodiscard]] std::string to_string(){
using namespace std;
using namespace std::string_literals;
return "("s + std::to_string( Coefficient ) +
string { "x^" } +
std::to_string( Power ) + ( sizeof...(Tail) == 0 ? ")" : ") + " ) +
polynomial<Tail...>::to_string();
}
private:
term< coeff<Coefficient> , power<Power> > m_t;
};
int main()
{
auto p1 = polynomial<term< coeff<1> , power<2> > ,
term< coeff<2> , power<4> > ,
term< coeff<2> , power<3> > ,
constant<3> ,
exponential<2> >{};
std::cout << "Polynomial is : " << p1.to_string() << std::endl;
std::cout << "f(2) : " << p1.eval( 2 ) << std::endl;
std::cout << "f(3) : " << p1.eval( 3 ) << std::endl;
return 0;
}
run online
Polynomial coefficients can be stored in std::array or std::vector(in case you define polynomial degree in runtime).
Then extend functionality with eval function.
template <unsigned N>
class Poly : public std::array<double, N> {
public:
template <typename... E>
Poly(E &&... e) : std::array<double, N>{{std::forward<E>(e)...}} {}
double eval(double x) {
double result = 0;
double exp = 1.;
for (auto it = this->rbegin(); it != this->rend(); ++it) {
result += exp * (*it);
exp *= x;
}
return result;
}
};
usage
double result = Poly<3>{3., 2., 1.}.eval(17);
template< typename T >
double GetAverage(T tArray[], int nElements)
{
T tSum = T(); // tSum = 0
for (int nIndex = 0; nIndex < nElements; ++nIndex)
{
tSum += tArray[nIndex];
}
// convert T to double
return double(tSum) / nElements;
};
template <typename T>
class pair {
public:
T a;
T b;
pair () {
a=T(0);
b=T(0);
} ;
pair (T a1, T b1) {
a=a1;
b=b1;
};
pair operator += (pair other_pair) {
return pair(a+other_pair.a, b+other_pair.b);
}
operator double() {
return double(a)+ double(b);
}
};
int main(void)
{
pair<int > p1[1];
p1[0]=pair<int >(3,4);
std::cout<< GetAverage <pair <int >>(p1,1) <<"\n";
}
I can't understand why it prints 0 instead of 3.5.
When I copy code from C++ -- How to overload operator+=? all went fine. But I can't understand where I have made
a mistake
pair operator += (pair other_pair) {
return pair(a+other_pair.a, b+other_pair.b);
}
should be
pair &operator += (const pair &other_pair) {
a += other_pair.a;
b += other_pair.b;
return *this;
}
You need to modify the members of this and return a reference to *this, instead of a new object.
It is also a good idea to pass other_pair as a const reference instead of by value.
I have the following problem:
template< typename Func >
class A
{
public:
A( Func f ) : _f( f ) {}
// ...
template< typename T_in = /*input type of _f */, typename T_out = /*output type of _f */ >
std::vector<T_out> operator()( const std::vector<T_in>& input)
{
std::vector<T_out> res( input.size() );
for( size_t i = 0 ; i < input.size() ; ++i )
res[ i ] = _f( input[ i ] );
return res;
}
private:
Func _f;
// ...
};
template< typename Func >
A<Func> A_wrapper( Func f )
{
return A<Func>( f );
}
int main()
{
// example for f(x) = x*x
std::vector<float> input = { /* ... */ };
auto f = []( float in ){ return in*in; };
auto map_square = A_wrapper( f );
auto res = map_square( input );
return 0;
}
As you can see above, I try to implement a class A whose function operator() maps a function _f to each element of an input vector input.
My problem is the following: I want the elements of the input vector input to have the input type of _f (i.e., T_in) and the elements of the output vector the output type of _f (i.e., T_out) but without passing the input/output type of _f explicitly to the class A, the function A_wrapper which I use for type deduction and/or the function operator() (due to a better readability of the code).
Has anyone an idea how the input/output type of _f can be deduced automatically at compile time?
Many thanks in advance.
BTW: The question here is related to my previous post Get input/output type of callable
Same question, same answer: you can deduce T_in from the input vector and T_out using std::result_of_t
#include <vector>
#include <functional>
template< typename Func >
class A
{
public:
A( Func f ) : _f( f ) {}
// ...
template< typename T_in,
typename T_out = std::result_of_t<Func(T_in)>>
std::vector<T_out> operator()( const std::vector<T_in> & input)
{
std::vector<T_out> res( input.size() );
for( size_t i = 0 ; i < input.size() ; ++i )
res[ i ] = _f( input[ i ] );
return res;
}
private:
Func _f;
// ...
};
template< typename Func >
A<Func> A_wrapper( Func f )
{
return A<Func>( f );
}
int main()
{
// example for f(x) = x*x
std::vector<float> input = { /* ... */ };
auto f = []( float in ){ return in*in; };
auto map_square = A_wrapper( f );
auto res = map_square( input );
return 0;
}
Using typename std::result_of<Func(T_in)>::type instead of std::result_of_t<Func(T_in)> should work also for C++11, not only for C++14.
in this question:
template; Point<2, double>; Point<3, double>
Dennis and Michael noticed the unreasonable foolishly implemented constructor.
They were right, I didn't consider this at that moment.
But I found out that a constructor does not help very much for a template class like this one, instead a function is here much more convenient and safe
namespace point {
template < unsigned int dims, typename T >
struct Point {
T X[ dims ];
std::string str() {
std::stringstream s;
s << "{";
for ( int i = 0; i < dims; ++i ) {
s << " X" << i << ": " << X[ i ] << (( i < dims -1 )? " |": " ");
}
s << "}";
return s.str();
}
Point<dims, int> toint() {
Point<dims, int> ret;
std::copy( X, X+dims, ret.X );
return ret;
}
};
template < typename T >
Point< 2, T > Create( T X0, T X1 ) {
Point< 2, T > ret;
ret.X[ 0 ] = X0; ret.X[ 1 ] = X1;
return ret;
}
template < typename T >
Point< 3, T > Create( T X0, T X1, T X2 ) {
Point< 3, T > ret;
ret.X[ 0 ] = X0; ret.X[ 1 ] = X1; ret.X[ 2 ] = X2;
return ret;
}
template < typename T >
Point< 4, T > Create( T X0, T X1, T X2, T X3 ) {
Point< 4, T > ret;
ret.X[ 0 ] = X0; ret.X[ 1 ] = X1; ret.X[ 2 ] = X2; ret.X[ 3 ] = X3;
return ret;
}
};
int main( void ) {
using namespace point;
Point< 2, double > p2d = point::Create( 12.3, 34.5 );
Point< 3, double > p3d = point::Create( 12.3, 34.5, 56.7 );
Point< 4, double > p4d = point::Create( 12.3, 34.5, 56.7, 78.9 );
//Point< 3, double > p1d = point::Create( 12.3, 34.5 ); //no suitable user defined conversion exists
//Point< 3, int > p1i = p4d.toint(); //no suitable user defined conversion exists
Point< 2, int > p2i = p2d.toint();
Point< 3, int > p3i = p3d.toint();
Point< 4, int > p4i = p4d.toint();
std::cout << p2d.str() << std::endl;
std::cout << p3d.str() << std::endl;
std::cout << p4d.str() << std::endl;
std::cout << p2i.str() << std::endl;
std::cout << p3i.str() << std::endl;
std::cout << p4i.str() << std::endl;
char c;
std::cin >> c;
}
has the new C++ standard any new improvements, language features or simplifications regarding this aspect of ctor of a template class?
what do you think about the implementation of the combination of namespace, stuct and Create function?
many thanks in advance
Oops
Since the array is public, it is an option to omit the constructor and allow aggregate initialization (like boost::array<T, N> for example).
Point<2, int> p = {1, 2};
This is no worse than having to call a create function. (The create function might still be handy as a utility.)
In C++0x you will be able to have all sorts of coolness. For example, play with variadic templates, to have it checked at compile-time if the constructor is called with a right number of arguments. (The following could also check if the arguments ...U are all of type T, with some more metaprogramming fun, but it might not be absolutely necessary.)
//helper to copy variable amount of arguments into an array
namespace detail {
template <class T, class U>
void copy_variadic(T* p, U value)
{
*p = value;
}
template <class T, class First, class ...Rest>
void copy_variadic(T* p, First var, Rest ...args)
{
*p = var;
copy_variadic(++p, args...);
}
} //detail
template < unsigned int dims, typename T >
struct Point {
T X[ dims ];
Point() : X{}
{
}
template <class ...U>
Point(U... args) {
static_assert(sizeof...(args) == dims, "Too many or too few arguments to Point constructor");
detail::copy_variadic(X, args...);
}
//...
};
(Actually, with some modifications - perfect forwarding - copy_variadic would make a nice addition to my collection of variadic-template utilities, if someone doesn't come and point out a significantly better way.)
Yes, as Michael pointed out in his answer to your previous question, in C++0x you'll be able to use an initializer list to pass an arbitrary number of arguments to your ctor. In your case, the code would look something like:
template <int dims, class T>
class point {
T X[dims];
public:
point(std::initializer_list<T> const &init) {
std::copy(init.begin(), init.begin()+dims, X);
}
};
You could create a point object with this something like:
point<3, double> x{0.0, 0.0, 0.0};
Personally, I'm not sure I like the basic design very well though. In particular, I'd rather see X turned into an std::vector, and determine the number of dimensions strictly from the parameter list that was passed instead of having it as a template argument:
template <class T>
class point {
std::vector<T> X;
public:
point(std::initializer_list<T> init) {
std::copy(init.begin(), init.end(), std::back_inserter(X));
}
};
This does have some trade-offs though -- points with a different number of dimensions are still the same type. For example, it basically asserts that it's reasonable to assign a 2D point to a 3D point, or vice versa.