I've got a few functions, some of which are overloaded and some are templates, ex.:
void fun1 (vector<string> &a, int b);
void fun1 (vector<double> &a, int b);
template <typename t>
void fun2 (t a[], int b);
and so on. Every function I use has a version for 2 data types, one is an array and the other one is a vector (a vector of strings, a vector of doubles, an array of strings and an array of doubles). The question is, can I create a template for an array of pointers? Is there any way of doing it, apart from:
void (*strvecfun[])(vector <string>&, long, long)={fun1, fun2};
void (*dblvecfun[])(vector <double>&, long, long)={fun1, fun2};
void (*strarrfun[])(string [], long, long)={fun1, fun2};
and so on?
You can use
template<typename Func>
struct func_array {
static Func *const data[];
};
template<typename Func>
Func *const func_array<Func>::data[] = { fun1, fun2 };
And later call
func_array<void(std::vector<double>&, long, long)>::data[0](dvec, l1, l2);
func_array<void(std::vector<string>&, long, long)>::data[1](svec, l1, l2);
// ...and so forth
This requires that there are matching overloads for all the signatures you're going to use of all functions you put into the list, naturally.
Instead of having 2 implementations, have one. Have your data take an array_view<double>:
template<class T>
struct array_view {
// can make this private:
T* b = 0; T* e = 0;
// core methods:
T* begin() const { return b; }
T* end() const { return e; }
// utility methods:
size_t size() const { return end()-begin(); }
T& front() const { return *begin(); }
T& back() const { return *std::prev(end()); }
bool empty() const { return begin()==end(); }
// core ctors:
array_view(T* s, T* f):b(s),e(f) {};
array_view()=default;
array_view(array_view const&)=default;
// derived ctors:
array-view(T* s, size_t l):array_view(s, s+l) {};
template<size_t N>
array_view( T(&arr)[N] ):array_view(arr, N) {};
template<size_t N>
array_view( std::array<T,N>&arr ):array_view(arr.data(), N) {};
template<class A>
array_view( std::vector<T,A>& v ):array_view(v.data(), v.size()) {};
// extra ctors that fail to compile if `T` is not const, but
// are mostly harmless even if `T` is not const, and useful if
// `T` is const. We could do fancy work to disable them, but
// I am lazy:
using non_const_T = std::remove_const_t<T>;
template<class A>
array_view( std::vector<non_const_T,A>const& v ):array_view(v.data(), v.size()) {};
template<size_t N>
array_view( std::array<non_const_T,N>const&arr ):array_view(arr.data(), N) {};
array_view( std::initializer_list<non_const_T> il ):array_view(il.data(), il.size()) {};
};
array_view acts like a view into a container, and can be implicitly converted from a number of std containers as well as raw arrays.
void fun1 (array_view<std::string> a);
a.size() tells you how long it is, and it can be iterated over in a for(:) loop even.
std::vector<T>& is far more powerful than what you need. By using array_view, we only expose what you need (access to elements), and thus are able to take both an array and a container.
If you pass in a "real" C style array, it will auto-deduce the length. If you instead pass in a pointer (or a [] really-a-pointer array), you also have to pass the length like:
fun1( {ptr, length} );
Create a function called max that will return the value of the largest element in an array.
The arguments to the function should be the address of the array size.
Make this function into a template so it will work with an array of any numerical types.
Related
I have the following situation. Let say we want to implement a sorted array data structure which keeps the array sorted upon insertion. At first attempt, I would do something like:
template<typename T, typename Comparator, Comparator comparator>
SortedArray {
public:
void find(T value);
void insert(T value);
void remove(T value);
}
The argument T is of course for the type of the elements in the array. Then I need a comparator to tell how to compare objects of type T so that I can keep the elements sorted. Since I want to allow for both function pointers (as in classical qsort) as well as function objects and maybe lambda as well, I need to add the template parameter for the comparator.
Now the problem is that I want the compiler to automatically deduce the 2nd Comparator argument based on the 3rd argument. Right now, a typical usage will be exploiting decltype like
int compare_int(int x, int y) {
return x - y;
}
SortedArray<int, decltype(compare_int), compare_int> myArray;
but this doesn't work with lambda and certainly I would love to just write
SortedArray<int, compare_int> myArray;
instead.
Any idea or is it actually possible in C++ at the moment?
You can non type template parameters as follows:
template<typename T, auto C >
class SortedArray
{
private:
std::vector<T> v;
public:
void sort(){ std::sort( v.begin(), v.end(), C );}
void print() { for( auto& el: v ) std::cout << el << std::endl; }
void push(T t){ v.push_back(t);}
};
bool compare_int( int a, int b )
{
return a<b;
}
int main()
{
SortedArray<int, compare_int> sa1;
sa1.push(5);
sa1.push(3);
sa1.push(7);
sa1.sort();
sa1.print();
SortedArray<int, [](int a, int b){ return a<b;} > sa2;
sa2.push(5);
sa2.push(3);
sa2.push(7);
sa2.sort();
sa2.print();
}
As you can see, you can also use a lambda as template parameter.
There is no need to do any template gymnastic with derived template parameters anymore.
I'm thinking about a function with signature
template<typename ...Ts>
std::vector<std::tuple<Ts...>> join_vectors(std::vector<Ts>&&...) {
//...
};
but probably a more general one accepting any iterable instead of just std::vector would be good. Probably it would have a signature like this?
template<template<typename> typename C, typename ...Ts>
C<std::tuple<Ts...>> join_vectors(C<Ts>&&...) {
// ...
};
However, I'm not at this level yet in C++ (despite doing the same in Haskell would be relatively easy), hence I seek for help.
Unfortunately, Range-v3's zip is not at my disposal in this case. I'm tagging it because I think those interested in it are in a better position to help me.
For any indexable containers with size something like this is possible:
#include <tuple>
#include <vector>
#include <algorithm>
// Copy from lvalue containers, move from rvalue containers.
template<typename ...Cs>
auto zip(Cs... vecs) {
std::vector<std::tuple<typename std::decay_t<Cs>::value_type...>> vec;
auto len = std::min({vecs.size()...});
vec.reserve(len);
for(std::size_t i=0;i<len;++i){
vec.emplace_back(std::move(vecs[i])...);
}
return vec;
};
//Return vector of tuples with & for non-const vecs and const& if const.
template<typename ...Cs>
auto zip_view(Cs&... vecs) {
std::vector<std::tuple<decltype(vecs[0])...>> vec;
auto len = std::min({vecs.size()...});
vec.reserve(len);
for(std::size_t i=0;i<len;++i){
vec.emplace_back(vecs[i]...);
}
return vec;
};
If the containers have properly implemented move constructors, this solution will copy the containers passed as lvalues and move from rvalue ones.
Very slight downside is that lvalue containers are copied whole first instead of only the individual elements.
Example [Godbolt]
#include <iostream>
#include <memory>
template<typename T, typename...Args>
void print_tuple(const T& first, const Args&... args){
std::cout<<'('<<first;
((std::cout<<','<< args),...);
std::cout<<')';
}
template<typename T>
struct helper{
using fnc_t = void;
};
template<typename...Args>
struct helper<std::tuple<Args...>>{
using fnc_t = void(*)(const Args&... args);
};
template<typename...Args>
struct helper<std::tuple<Args&...>>{
using fnc_t = void(*)(const Args&... args);
};
template<typename T>
using fnc_t2 = typename helper<T>::fnc_t;
template<typename T>
void template_apply(fnc_t2<T> f, const T& tuple){
std::apply(f, tuple);
}
template<typename T>
void print_vec(const std::vector<T>& vec){
for(const auto&e:vec){
template_apply(print_tuple,e);
std::cout<<'\n';
}
}
struct MoveOnlyFoo{
MoveOnlyFoo(int i):m_i(i){}
int m_i;
std::unique_ptr<int> ptr = nullptr;
};
std::ostream& operator<<(std::ostream& o, const MoveOnlyFoo& foo){
return o<<foo.m_i;
}
int main(){
std::vector v1{1,2,3,4,5,6};
std::vector v2{'a','b','c','d','e'};
std::vector v3{1.5,3.5,7.5};
std::vector<MoveOnlyFoo> vmove;
vmove.emplace_back(45);
vmove.emplace_back(46);
vmove.emplace_back(47);
const std::vector v4{-1,-2,-3,-4,-5};
//Move rvalues, copy lvalue.
print_vec(zip(v1,v2,v3, v4, std::move(vmove)));
// This won't work since the elements from the last vector cannot be copied.
//print_vec(zip(v1,v2,v3, v4, vmove));
std::cout<<"View:\n";
//View, provides const& for const inputs, & for non-const
print_vec(zip_view(v1,v2,v3,v4));
std::cout<<"Modify and print:\n";
for(auto& [x,y]: zip_view(v1,v2)){
++x,++y;
}
// Note the view can work with const containers, returns tuple of `const T&`.
print_vec(zip_view(std::as_const(v1),std::as_const(v2)));
}
Output
(1,a,1.5,-1,45)
(2,b,3.5,-2,46)
(3,c,7.5,-3,47)
View:
(1,a,1.5,-1)
(2,b,3.5,-2)
(3,c,7.5,-3)
Modify and print:
(2,b)
(3,c)
(4,d)
(5,e)
(6,f)
Please disregard the readability of the printing code ;)
I modeled it after python zip functionality. Note your initial proposal copies the vectors, so the output is a vector with the values moved from the parameters.
Returning an iterable Cs is harder because you would have to specify how to insert elements into it, iterators cannot do it on their own.
Getting it work with iterators (but returning still a vector) is a chore, but in theory also possible.
class Organization {
private:
vector<unique_ptr<Employee>> employees_;
vector<unique_ptr<Item>> items_;
}org;
I need to have a facility outside the class to iterate over the employees and items and call their members, like the following...
for(auto const& e : getEmployees()) { e.get()->getName(); }
But I cannot make getEmployees() function to return employees_, as vector of unique_ptrs is not copyable
So currently I'm having a for_each_employee function
template<class callable>
void Organization::for_each_employee(callable f) {
for(auto const& e : employees_) {
f(e.get());
}
}
// And I use it like,
org.for_each_employee([](Employee* e){ e->getName(); });
But I do not like this idea as I'll have to write for_each_employee and for_each_item. I have similar other classes of the similar structure. So I will end up writing lot of for_each_XX type functions. This is not what I want.
Can I have generic for_each function that are friends of these classes (like Organization that contain vector of unique_ptrs)?
How to iterate (outside a class) a private member which is a vector<unique_ptr<T>>
The simplest and quite readable approach is to provide an access method that returns a possibly const-qualified reference to the data member. This way, you don't try to copy non-copyable members.
const vector<unique_ptr<Item>>& getItems()
{
return items_;
}
which can be used like this
for (const auto& item : organizationInstance.getItems())
item->doStuff();
You can return reference of employee_ in getEmployees() to iterate
const vector<unique_ptr<Employee>>& getEmployees()
{
return employee_;
}
What you're looking for is iterators. std::vector::begin() and std::vector::end() return iterators to the first and to the one-past-the-end elements of the vector. Then you can do stuff like.
for (auto iter = organization.get_employees_begin(); iter != organization.get_employees.end(); ++iter) {
do_something(*iter);
}
Where
class Organization {
auto get_employees_begin() { return employees_.begin(); }
auto get_employees_begin() const { return employees_.begin(); }
auto get_employees_end() { return employees_.end(); }
auto get_employees_end() const { return employees_.end(); }
}
The const versions return const iterators, which are similar to pointers-to-const in that they don't allow modification of the vector. The added benefit of this method over returning a reference to the vector is that it completely decouples the implementation from the interface. If you don't care about that for whatever reason, you can use this instead.
class Organization {
auto& get_employees() { return employees_; }
const auto& get_employees() const { return employees_; }
}
This will allow you to use all vector utilities but it will also make all your code that relies on them break if the internal container changes from a vector to something else.
In any case, you might not want to provide the non-const functions if the vector should not be modified directly.
To allow only iterating, not giving any more vector-specific operations You can use boost::range
auto getItems() {
return boost::make_iterator_range(employees_.begin(), employees_.end());
}
Here is a simple span class. It is similar to gsl::span. It represents a view into a contiguous buffer of T elements (like in an array):
template<class T>
struct span {
T* begin() const { return b; }
T* end() const { return e; }
T* data() const { return begin(); }
std::size_t size() const { return end()-begin(); }
bool empty() const { return size()==0; }
span( T* s, T* f ):b(s),e(f) {}
span( T* s, std::size_t length ):span(s, s+length){}
span() = default;
template<class A>
span( std::vector<T, A>& v ):
span(v.data(), v.length() )
{}
template<class A>
span( std::vector<std::remove_const_t<T>, A> const& v ):
span(v.data(), v.length() )
{}
template<std::size_t N>
span( T(& arr)[N] ):
span(arr, N)
{}
template<std::size_t N>
span( std::array<T, N>& arr ):
span(arr.data(), N)
{}
template<std::size_t N>
span( std::array<std::remove_const_t<T>, N> const& arr ):
span(arr.data(), N)
{}
private:
T* b = 0;
T* e = 0;
};
simply have your getEmployees return a span<std::unique_ptr<Employee> const>.
This exposes everything the caller needs to iterate over it efficiently, and no more.
The simpler alternative is to return a std::vector<std::unique_ptr<Employee>> const&, but that leaks implementation details that are utterly irrelevant to the consumer of getEmployee.
I am creating a function which should take as input iterators to vector
for example:
vector<int> a;
foo(a.begin(),a.end())
The vector can hold any type.
Now the simple way to do this is using templates
template <typename Iterator>
void foo(Iterator first, Iterator last) {
for (Iterator it = first; it!=last; ++it) {
cout << *it;
}
}
I want to know if there is a way to achieve the same functionality without using templates. Since using Templates would force me to include these functions in Header file of a public API which I don't want to. So I wanted to know is there an alternate way to access the iterators without using Templates.
There are ways not to include the implementation in header files but they are not clean to implement (for instance you should know in advance the instantiations). Read here for more info about this issue:
Why can’t I separate the definition of my templates class from its declaration and put it inside a .cpp file?
How can I avoid linker errors with my template functions?
For instance in:
foo.h
#ifndef HI_
#define HI_
template<class Iterator>
void foo(Iterator first, Iterator last);
#endif
foo.cpp
#include "stack.h"
using namespace std;
template<class Iterator>
void foo(Iterator first, Iterator last) {
for (Iterator it = first; it != last; ++it) {
cout << *it << " ";
}
}
template
void foo( std::vector<int>::iterator first, std::vector<int>::iterator last);
template
void foo( std::vector<double>::iterator first, std::vector<double>::iterator last);
Now you can use foo function only for double and int. Other types won't link.
Hope this helps.
This is a long answer. The short answer is "type erasure"; go learn about it.
The long answer is two answers. First I cover "do you just want to be able to iterate over contiguous ints?". Then you want span. This is a really simple form of type erasure that forgets what the exact container is you are working on so long as it is contiguous and over T.
The second answer is if you actually need to deal with multiple types (not just int) and multiple kinds of containers (not just contiguous ones).
The two answers are separated by a line.
The span concept (see gsl::span) is designed for pretty much this reason. It itself is a template (over the type you are working with), but it will be a concrete instance of a template in most interfaces.
Here is a toy version of it:
template<class T>
struct span_t {
T* b = 0;
T* e = 0;
T* begin() const { return b; }
T* end() const { return e; }
span_t(span_t const&)=default;
span_t& operator=(span_t const&)=default;
span_t()=default;
span_t( T* s, T* f ):b(s),e(f) {}
span_t( T* s, std::size_t l):span_t(s, s+l){}
template<std::size_t N>
span_t( T(&arr)[N] ):span_t(arr, N) {}
std::size_t size() const { return end()-begin(); }
bool empty() const { return begin()==end(); }
T& front() const { return *begin(); }
T& back() const { return *(std::prev(end()); }
T* data() const { return begin(); }
span_t without_front( std::size_t N=1 ) const {
return {std::next( begin(), (std::min)(N, size()) ), end()};
}
span_t without_back( std::size_t N=1 ) const {
return {begin(), std::prev(end(), (std::min)(N, size()) )};
}
};
we can augment it with conversion operators
namespace details {
template<template<class...>class Z, class, class...Ts>
struct can_apply:std::false_type{};
template<class...>using void_t=void;
template<template<class...>class Z, class...Ts>
struct can_apply<Z, void_t<Z<Ts...>>, Ts...>:std::true_type{};
}
template<template<class...>class Z, class...Ts>
using can_apply = details::can_apply<Z,void,Ts...>;
template<class C>
using dot_data_r = decltype( std::declval<C>().data() );
template<class C>
using dot_size_r = decltype( std::declval<C>().size() );
template<class C>
using can_dot_data = can_apply< dot_data_r, C >;
template<class C>
using can_dot_size = can_apply< dot_size_r, C >;
can_dot_data detects via SFINAE if .data() is valid to do on an object of type C.
Now we add a constructor:
template<class T,
std::enable_if_t<
can_dot_data<T&>{}
&& can_dot_size<T&>{}
&& !std::is_same<std::decay_t<T>, span_t>{}
, int
> =0
>
span_t( T&& t ): span_t( t.data(), t.size() ) {}
which covers std::vector and std::string and std::array.
Your function now looks like:
void foo(span_t<int> s) {
for (auto&& e:s)
std::cout << s;
}
}
with use:
std::vector<int> a;
foo(a);
now, this only works for contiguous containers of a specific type.
Suppose this is not what you want. Maybe you do need to solve this for a myriad of types, and you don't want to expose everything in the header.
Then what you need to do is known as type erasure.
You need to work out what minimal set of operations you need from the provided types. Then you need to write wrappers that "type erase" these operations down to "typeless" operations.
This goes in the header, or in another helper header.
In the interface of the function, or in a header intermediate helper, you take the incoming types and do the type erasure, then pass the type-erased types into the "real" implementation.
An example of type erasure is std::function. It takes almost anything that can be invoked with a fixed signature, and turns it into a single type-erased type. Everything except how to copy, destroy and invoke an instance of the type is "forgotten" or erased.
For your case:
template <typename Iterator>
void foo(Iterator first, Iterator last) {
for (Iterator it = first; it!=last; ++it) {
cout << *it;
}
}
I see two things that need to be erased down to; iteration, and printing.
struct printable_view_t {
void const* data = 0;
void(*print_f)(std::ostream& os, void const*) = 0;
explicit operator bool()const{return data;}
printable_view_t() = default;
printable_view_t(printable_view_t const&) = default;
template<class T,
std::enable_if_t<!std::is_same<T, printable_view_t>{}, int> =0
>
printable_view_t( T const& t ):
data( std::addressof(t) ),
print_f([](std::ostream& os, void const* pv){
auto* pt = static_cast<T const*>(pv);
os << *pt;
})
{}
std::ostream& operator()(std::ostream& os)const {
print_f(os, data);
return os;
}
friend std::ostream& operator<<(std::ostream& os, printable_view_t p) {
return p(os);
}
};
printable_view_t is an example of type-erasing "I can be printed".
void bar( printable_view_t p ) {
std::cout << p;
}
void test_bar() {
bar(7);
bar(3.14);
bar(std::string("hello world"));
}
The next thing we'd have to do is type erase iteration. This is harder, because we want to type erase iteration over iterating over a printable_view_t type.
Type erasing foreach is a tad easier, and often more efficient.
template<class View>
struct foreach_view_t {
void* data = 0;
void(*func)( std::function<void(View)>, void* ) = 0;
explicit operator bool()const{return data;}
foreach_view_t() = default;
foreach_view_t(foreach_view_t const&) = default;
template<class T,
std::enable_if_t<!std::is_same<std::decay_t<T>, foreach_view_t>{}, int> =0
>
foreach_view_t( T&& t ):
data( const_cast<std::decay_t<T>*>(std::addressof(t)) ),
func([](std::function<void(View)> f, void* pv){
auto* pt = static_cast<std::remove_reference_t<T>*>(pv);
for (auto&& e : *pt)
f(decltype(e)(e));
})
{}
void operator()(std::function<void(View)> f)const{
func(f, data);
}
};
we then daisy chain these together
void foo(foreach_view_t<printable_view_t> x) {
x([](auto p){ std::cout << p; });
}
test code:
std::vector<int> a{1,2,3};
foo(a);
Now much of the header code was "hoisted" into the type erasure types instead of a function template body. But careful choice of the points of type erasure can let you keep what you need from the types precise and narrow, and the logic of how you use those operations private.
As an example, the above code doesn't care where you are printing it to; std::cout was not part of the type erasure.
Live example.
I want to know if there is a way to achieve the same functionality without using templates. [...] I wanted to know is there an alternate way to access the iterators without using Templates.
Yes, if you use C++14, but...
Since using Templates would force me to include these functions in Header file of a public API which I don't want to.
... isn't a useful way for you because it's equivalent to use templates and you have to put it in the header file.
In C++14 you can use a lambda function with auto parameters.
auto foo = [](auto first, auto last)
{ for (auto it = first ; it != last; ++it ) std::cout << *it; };
The autos aren't template (from a formal point of view) but are equivalent and you can't declare foo in the header and develop it in a cpp file.
I've wanted a wrapper around arrays, such, it would be stored at the stack - to be not concerned about memory releasing - be initializable via brace lists, and possibly be substitutable in any place of an ordinary array. Then, I've produced the following code. And now am wondering, have I missed something. -- So - is it what I've wanted?
template<class T, size_t size>
struct Array
{
T body[size];
operator T* () { return body; }
};
Edit:
I might be imprecise. The wrapper is only for constructional purpose. It shall be used for constructing arrays from brace lists, when being in an initialization list (primarily). Like
class A {
protected: A(int array[])
...
class B : public A {
public: B() :
A( (Array<int, 2>) {{ 1, 2 }} )
...
There was a proposition of a const version of the casting operator. - I've been considering this, but am not sure, is it really needed. While casting to const T[] is done implicitly through the existing operator, and a constant array can be defined by giving T = const ..., is there still a reason?
For a basic example, I don't think there's much you can improve on, except for a few helper functions. In particular, it would be nice to have a method that returns the size:
constexpr std::size_t size() const { return size; }
In addition, here are a few others:
const/non-const overloads of operator[N]:
As #ChristianRau stated in the comments, a operator T* provides a non-const version. We can implement the const version as such:
T const& operator [](std::size_t n) const
{
return body[n];
}
// similarly for non-const:
T& operator [](std::size_t n) { return body[n]; }
begin() and end() sequencers (very useful e.g. for the C++11 range-based for):
T* begin() { return body; }
T* end() { return body + size; }
// const versions... very much the same
T const* cbegin() const { return body; }
T const* cend() const { return body + size; }
T const* begin() const { return cbegin(); }
T const* end() const { return cend(); }
an at() method, which includes bounds checking (as opposed to operator[] by convention):
T const& at(std::size_t offset) const
{
// You should do bounds checking here
return body[offset];
}
// also a non-const version again..
It would also be nice to have a constructor that takes an std::initializer_list<T> so that you don't have to use the aggregate-initialization:
#include <algorithm>
#include <initializer_list>
template <typename T, std::size_t N>
struct Array
{
...
Array(std::initializer_list<T> const& list)
{
std::copy(list.begin(), list.end(), body);
}
...
};
Here is another one suggested by #DyP (initializer list always copies, perfect forwarding tries to avoid that):
template <typename T, std::size_t N>
struct Array
{
...
template <typename... Args>
// possibly constexpr
Array(Args&&... args) : body{ std::forward<Args>(args)... }
{}
...
};
Here is the program in action if you want to see it -- http://ideone.com/Zs27it#view_edit_box
There are others features you can include, but as I said this is a basic example, and you would most likely be better off using something like std::array which has more or less the same methods.