Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I'm learning C++ Expression Templates these days, I've read a lot of articles. Still confused about how to design an express template.
Is there any standard way(steps) when we design Expression Templates, in other words , how to design, including what classes should I create and what operations should I performed in specific functions?
Let's say Matrix computations.
I know how to write it via overloading C++ operators, but after I finish it by overloading coperators I don't know how to write it using Expression Templates.
The main idea of having an expression template is to use lazy evaluation, i.e. only compute result when using an expression that uses the addition, subtraction, etc. expression for specific index, instead of computing the result for all the values of the arrays in the constructor.
Have a "sum" class with two variable members, where each represent the arrays that you want to add (As you add more than two arrays, this class will be used "recursively" as I'll show below). For this you need to have a class with 2 template arguments for each member, and have an operator[] which returns the addition of both arrays for specific location, i.e.
int operator[](const int i) const
{
return a[i] + b[i];
}
Have a "starting" class which initializes the values of your arrays. Note that this class is different from the above, as it will only store 1 array. Also this class must implement operator[] as follows:
int operator[](const int i) const
{
return starting_vector[i];
}
Have an overload operator+ to add your "starting" vector (from 2 bullet) with other ones, and to store them in the "sum" class (from 1 bullet) as:
template <typename A, typename B>
VectorSum<A, B> operator+(const A v1, const B v2)
{
return VectorSum<A, B>{v1, v2};
}
Below is a complete example that compiles:
#include <initializer_list>
#include <iostream>
#include <stdexcept>
#include <vector>
class Vector
{
public:
explicit Vector(const std::initializer_list<int>& vec)
{
for (const auto x : vec)
{
starting_vector.push_back(x);
}
}
int operator[](const int i) const
{
return starting_vector[i];
}
std::size_t size() const
{
return starting_vector.size();
}
private:
std::vector<int> starting_vector;
};
template <typename A, typename B>
class VectorSum
{
public:
VectorSum(const A& other_a, const B& other_b):
a{other_a}, b{other_b}
{
if (other_a.size() != other_b.size())
{
throw std::invalid_argument{"must be same sizes"};
}
}
int operator[](const int i) const
{
return a[i] + b[i];
}
std::size_t size() const
{
return a.size();
}
private:
const A a;
const B b;
};
template <typename A, typename B>
VectorSum<A, B> operator+(const A v1, const B v2)
{
return VectorSum<A, B>{v1, v2};
}
int main()
{
Vector v1{{1,2,3,4,100}};
Vector v2{{1,2,3,4,1}};
Vector v3{{1,2,3,4,2}};
Vector v4{{1,2,3,10,5}};
VectorSum<VectorSum<VectorSum<Vector, Vector>, Vector>, Vector> sum {v1 + v2 + v3 + v4};
std::cout << sum[0] << std::endl;
}
Related
I have a cusom implemented Heap for priority queue application
class Heap {
SomeCutsomClass elements[100];
....
....
};
Now I need to support two different comparison operation between the keys of the heap and I want to implement it using c++ predicates
struct less1
{
bool operator()(const SomeCutsomClass& c1, const SomeCutsomClass& c1)
{
//specific implementation
}
};
struct less2
{
bool operator()(const SomeCutsomClass& c1, const SomeCutsomClass& c1)
{
//specific implementation
}
};
Ideally I should be able to pass the predicates somehow in the constructor of Heap
I am not able to visualize how to achieve this.
It is not that I want to use only predicates.Since I cant overload same operator twice in SomeCutsomClass , I am trying to use predicates.
I tried looking up STL source code of some well known data structures like std::sort etc , but they look complicated to me.
Here is an example containing both an example of std::less use and custom predicates as functions (lambdas).
#include <cassert>
#include <array>
#include <iostream>
#include <functional>
// Make heap a class template
// this allows you to specialize easily for any class
// I added the STL like third template parameter as example
// type_t is the type to store in the heap
// N is the size of the heap
template<typename type_t, std::size_t N, class Compare = std::less<type_t>>
class Heap
{
public:
using pred_t = std::function<bool(const type_t&, const type_t&)>;
Heap() :
m_predicate{ Compare() }
{
}
explicit Heap(pred_t predicate) :
m_predicate{ predicate }
{
}
bool compare(const int a, const int b)
{
return m_predicate(a, b);
}
private:
std::array<type_t, N> m_elements;
pred_t m_predicate;
};
struct SomeCustomClass
{
// all you need to make SomeCustomClass usable in Heap
// if it uses std::less as third template parameter
// is to provide this compare overload
bool operator<(const SomeCustomClass& other) const
{
return m_value < other.m_value;
}
int m_value{};
};
int main()
{
// this heap will use std::less
Heap<int, 100> less_heap;
assert(less_heap.compare(1, 2));
// create a lambda predicate
auto pred = [](const int& lhs, const int& rhs)
{
return lhs > rhs;
};
// this heap will use custom predciate
Heap<int, 100> greater_heap(pred);
assert(greater_heap.compare(2,1));
//
Heap<SomeCustomClass, 10> custom_heap;
return 0;
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Herb Sutter states Almost Always Auto and I have the following code:
using count_t = int;
count_t get_count() { ... };
const auto count = get_count();
for (decltype(count) i = 0; i < count; i++) {
// Do the stuff
}
Essentially, using decltype() allows me to write a for loop that may use any integer type (hoping that get_count() would never return floating point) without any modifications in a client code of get_count() function and avoid compilation warnings like "signed-unsigned" mismatch.
My question is: is this form acceptable at all in an assumption that count_t may be redefined in future?
If using Boost is an option, you can avoid all the noise
#include <boost/range/irange.hpp>
for(auto i : boost::irange(get_count()))
The single argument version of boost::irange was introduced in 1.68, so you will need to copy the implementation for earlier versions.
To still be AAA, you might go to:
for (auto i = decltype(count){}; i != count; ++i) { /*..*/ }
template<class T>
struct indexer_t {
T t;
T operator*()const{return t;}
void operator++(){++t;}
friend bool operator==(indexer_t const& lhs, indexer_t const& rhs) {
return lhs.t==rhs.t;
}
friend bool operator!=(indexer_t const& lhs, indexer_t const& rhs) {
return lhs.t!=rhs.t;
}
};
template<class It>
struct range_t {
It b,e;
It begin() const { return b; }
It end() const { return e; }
};
template<class T>
range_t<indexer_t<T>> count_over( T const& s, T const& f ) {
return { {s}, {f} };
}
template<class T>
range_t<indexer_t<T>> count_upto( T const& t ) {
return count_over<T>( 0, t );
}
for (auto i : count_upto(count))
{
// Do the stuff
}
indexer_t and range_t can be improved; they are both minimal implementations.
Here is another alternative. I won't declare it to be better or worse than your own suggestion:
for (auto i = 0 * count; i < count; i++) {
Note that, as mentioned in comments, this behaves differently compared to yours in case type of count is smaller than int in which cases my i is promoted.
That said, index based loops can usually (perhaps always?) be converted to an iterator based loop, where auto deduction is more natural.
There is many primitive structs (several hundreds), that are used to transfer data between two components (for example a player and a server). There are no methods in them, just raw data.
The task is to write all requests and answers to be able to replay a player scenario without a server (we remember all question and all answers, that are pure functions).
So the task is put this structs in map without comparator. Now we use memcmp, it allows not to think about changes in this structs and it is compact, but there are too many problems with padding and etc.
Is it possible to get smth like getHashValue or any default comparator with metaprogramming in c++?
Conditions:
1) I do not want to create a comparator for each struct.
2) I want to have an error if a field was added or deleted if it breaks existing behavior and needs fix.
3) I don't want to change header files with struct definitions.
Example of a struct
struct A {
int a;
int b;
c c;
}
bool operator<(const A& a1, const A& a2)
{
if (a1.a != a2.a) return a1.a < a2.a;
if (a1.b != a2.b) return a1.b < a2.b;
if (a1.c != a2.c) return a1.c < a2.c;
return false;
}
I can consider other languages to implement this exact part (collect questions/answers), if it will not require to describe all this structs on that language again.
In C++17 you can pull this off if you are willing to (A) hard code how many elements are in each struct somewhere, and (B) write or generate code for each count of number of elements in the struct.
template<std::size_t N>
using size_k = std::integral_constant<std::size_t, N>;
template<class T>
auto auto_tie( size_k<0>, T&& t ) {
return std::tie();
}
template<class T>
auto auto_tie( size_k<1>, T&& t ) {
auto& [ x0 ] = std::forward<T>(t);
return std::tie( x0 );
}
template<class T>
auto auto_tie( size_k<2>, T&& t ) {
auto& [ x0, x1 ] = std::forward<T>(t);
return std::tie( x0, x1 );
}
// etc
now, in the namespace of the struct in question, write
struct foo {
int x;
};
struct bar {
int a, b;
};
size_k<1> elems( foo const& ) { return {}; }
size_k<2> elems( bar const& ) { return {}; }
an elems function that return the size_k counting how many elements.
Now in the namespace of the structs, write:
template<class T, class Size=decltype(elems(std::declval<T const&>()))>
bool operator<( T const& lhs, T const& rhs ) {
return auto_tie( Size{}, lhs ) < auto_tie( Size{}, rhs );
}
and you are done.
Test code:
foo f0{1}, f1{2};
bar b0{1,2}, b1{-7, -3};
std::cout << (f0<f1) << (f1<f0) << (f0<f0) << "\n";
std::cout << (b0<b1) << (b1<b0) << (b0<b0) << "\n";
Live example.
Getting further than this will require writing 3rd party tools or waiting for reflection extension to C++, maybe in C++20 or 23.
If you get elems wrong, I believe the structured bindings code in auto_tie should generate an error.
I suppose you could write your own compare operator based upon memcmp.
bool operator<(const A &lhs, const A &rhs) {
return memcmp(&lhs, &rhs, sizeof(A)) < 0;
}
Off course, writing these for each object might be a burden, so you could write a template for this. Though without some SFINAE it will cover too much types.
#include <type_traits>
#include <cstring>
template<typename T>
std::enable_if_t<std::is_pod_v<std::decay_t<T> //< Check if POD
&& !std::is_fundamental_v<std::decay_t<T>>>, //< Don't override for fundamental types like 'int'
bool>
operator<(const T &lhs, const T &rhs) {
return memcmp(&lhs, &rhs, sizeof(std::decay_t<T>)) < 0;
}
EDIT: Note that this technique requires you to zero-initialize the structs.
Looks like the best way to do it is to write a generator, that will generate .h and .cpp with bool operator< for all types in this header file. Then add this project as pre-build step to the main.
It doesn't look like a nice solution, but it allows to avoid hand-written code duplication and will support adding/removing new structs/fields. So I didn't find a better way.
I'm not an advanced programmer. How can I overload the [] operator for a class that has two (or more) array/vector type variables?
class X
{
protected:
std::vector<double> m_x, m_y;
public:
double& operator[](const short &i) { return ???; }
};
What should I use for ???, or how can I do it (maybe adding other definitions?) to be able to call either variable?
Additional question: will this allow other classes of type class derived : public X access m_x and m_y for writing?
UPDATE:
Thank you everyone who answered, but I'm afraid that if I draw the line then the answer to my first question is no, and to the second yes. The longer version implies either an extra struct, or class, or plain setters/getters, which I wanted to avoid by using a simple function for all.
As it stands, the current solution is a (temporary) reference to each variable, in each class to avoid the extra X:: typing (and keep code clear), since m_x would have existed, one way or another.
you can write just a function for this, like:
double &get(unsigned int whichVector, unsigned int index)
{
return (whichVector == 0 ? m_x[index] : m_y[index]);
}
or use operator():
struct A
{
std::vector<int> a1;
std::vector<int> a2;
int operator()(int vec, int index)
{
return (vec == 0 ? a1[index] : a2[index]);
}
};
A a;
auto var = a(0, 1);
but still, this is kinda strange :) probably you should just give a const ref outside, like:
const std::vector<double> &getX() const { return m_x; }
and second question: protected will be convert into private in public inheritance (child/derived will have access to these memebers)
Assuming you want m_x and m_y indexed against the same parameter and a single return value:
struct XGetter
{
double& x;
double& y;
};
XGetter operator[](const short &i) { return { m_x[i], m_y[i] }; }
And the const overload:
struct XGetterReadOnly
{
double x;
double y;
};
XGetterReadOnly operator[](const short &i) const { return { m_x[i], m_y[i] }; }
The compiler will make a good job of optimizing away the intermediate classes XGetter and XGetterReadOnly where appropriate which maybe hard to get your head round if you're a new to C++.
If using mixin doesn't make you uncomfortable you could use tag dispatching like:
#include <utility>
#include <vector>
#include <iostream>
template <size_t I>
struct IndexedVector {
std::vector<double> v;
IndexedVector():v(10){}
};
template <size_t I>
struct tag {
int i;
};
template <size_t S, class = std::make_index_sequence<S>>
struct MixinVector;
template <size_t S, size_t... Is>
struct MixinVector<S, std::index_sequence<Is...>>: IndexedVector<Is>... {
template <size_t I>
double &operator[](tag<I> i) {
return IndexedVector<I>::v[i.i];
}
};
int main() {
MixinVector<2> mv;
mv[tag<0>{0}] = 1.0;
std::cout << mv[tag<0>{0}] << std::endl;
}
To use std::index_sequence you need however compiler supporting c++14 (you could though implement it yourself in c++11). The approach is easily expandable to any number of vectors by simple MixinVector template parameter modification.
There are many broken things, either at conceptual and design level.
Are you able to point your finger simultaneously against two distinct things? No? That's why you cannot use one index to address two distinct vector retaining their distinction.
You can do many things: whatever way to "combine" two value int one is good
by a syntactic point of view:
return m_x[i]+m_y[x] or return sin(m_x[i])*cos(m_y[i]) or return whatever_complicated_expression_you_like_much
But what's the meaning of that? The point is WHY THERE ARE TWO VECTOR IN YOUR CLASS? What do you want them to represent? What do you mean (semantically) indexing them both?
Something I can do to keep their distinction is
auto operator[](int i) const
{ return std::make_pair(m_x[i],m_y[i]); }
so that you get a std::pair<double,double> whose fist and second members are m_x[i] and m_y[i] respectively.
Or ... you can return std::vector<double>{m_x[i],m_y[i]};
About your other question: Yes, inheriting as public makes the new class able to access the protected parts: that's what protected is for.
And yes, you cam R/W: public,protected and private are about visibility, not readability and writeability. That's what const is about.
But again: what does your class represent? without such information we cannot establish what make sense and what not.
Ok, stated your comment:
you need two different funcntions: one for read (double operator[](unsigned) const) and one for write (double& operator[](unsigned) const)
If you know vectors have a known length -say 200-, that you can code an idex transforamtion like i/1000 to identify the vector and i%1000 to get the index,so that 0..199 addres the first, 1000..1199 address the second 2000..2199 address the third... etc.
Or ... you can use an std::pair<unsigned,unsigend> as the index (like operator[](const std::pair<unsigned,unsigned>& i), using i.first to identify the vector, and i.second to index into it, and then call x[{1,10}], x[{3,30}] etc.
Or ... you can chain vetor together as
if(i<m_x.size()) return m_x[i]; i-=m_x:size();
if(i<m_y.size()) return m_y[i]; i-=m_y:size();
if(i<m_z.size()) return m_z[i]; i-=m_z:size();
...
so that you index them contiguously.
But you can get more algorithmic solution using an array of vectors instead of distinct vector variables
if you have std::array<std::vector<double>,N> m; instead of m_x, m_y and m_z the above code can be...
for(auto& v: m)
{
if(i<v.size()) return v[i];
i-=v.size();
}
You can return a struct has two double
struct A{
double& x;
double& y;
A(A& r) : x(r.x), y(r.y){}
A(double& x, double& y) : x(x), y(y){}
};
class X
{
protected:
std::vector<double> m_x, m_y;
public:
A operator[](const short &i) {
A result(m_x[i], m_y[i]);
return result;
}
};
Thank for editing to #marcinj
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Can anyone explain me the advantages of function poiner?
I know that there are many possible duplicates with my question but they only explain in words , that's not very helpful , I need an example of the case that not using the function pointer compare to the case of using the function pointer.
Thanks a lot.
How about mapping data to behaviour, things like:
void DoIt();
void DontDoIt();
std::map<std::string, std::function<void()> word_map {
{"DoIt", DoIt},
{"DontDoIt", DontDoIt}
};
std::string word;
// ... get "DoIt" or "DontDoIt" into word
word_map[word](); // execute correct function
Simple example : suppose you have N record comprising of names and phone numbers.
You're asked to sort
based on names
based on phone numbers
A nice approach would just be to vary a comparison function passed as a function pointer inside a sorting routine.
void sort( records r[], int N,
bool (*fptr)( const record& lhs, const record& rhs ) ) { }
If you won't use function pointer you'll end up coding same logic merely for two different comparison function.
void sort_by_name( records r[], int N) { }
void sort_by_phoneno( records r[], int N) { }
By using a function pointer you can, for example, prevent code duplication.
Without function pointers:
void AddOneToVectorElements( vector<int> v )
{
// implementation
}
void MultiplyVectorElementsByTwo( vector<int> v )
{
// implementation
}
// usage
AddOneToVectorElements(v);
MultiplyVectorElementsByTwo(v);
Using function pointers:
typedef int (*func)(int);
int TransformVecotr ( vector<int> v, func f)
{
// implementation by application of f to every element
}
int AddOne(int x)
{
return x + 1;
}
int MultiplyByTwo(int x)
{
return 2 * x;
}
// usage
TransformVecotr(v, &AddOne);
TransformVecotr(v, &MultiplyByTwo);
In C++11 there are lambda functions and they make the whole thing even more convenient.
The key point is that function pointers are used "under the hood" all the time in generic programming. One tends to forget this, because template argument deduction hides the function pointer syntax.
For example:
#include <algorithm>
#include <iterator>
bool f(int i)
{
return i == 1;
}
int main()
{
int arr[] = { 1, 1, 3 };
int count = std::count_if(std::begin(arr), std::end(arr), f);
}
The f in main's last line is a function pointer, because the std::count_if template function will accept anything that can be used with the () syntax. Quoting cppreference.com:
template< class InputIt, class UnaryPredicate >
typename iterator_traits<InputIt>::difference_type
count_if( InputIt first, InputIt last, UnaryPredicate p );
UnaryPredicate can be a function pointer, and is one in the example above.
The compiler just deduces its exact type, bool(*)(int), automatically when you pass f. Technically, you could also write the call like this:
// just for illustration:
std::count_if<int*, bool(*)(int)>(std::begin(arr), std::end(arr), f);
If there were no function pointers in C++, then you could not directly use functions as predicates in the standard-library algorithms. You'd instead have to wrap them in classes all the time:
#include <algorithm>
#include <iterator>
bool f(int i)
{
return i == 1;
}
struct Functor
{
bool operator()(int i) const
{
return f(i);
}
};
int main()
{
int arr[] = { 1, 1, 3 };
int count = std::count_if(std::begin(arr), std::end(arr), Functor());
}