Related
I have a function that takes a vector-like input. To simplify things, let's use this print_in_order function:
#include <iostream>
#include <vector>
template <typename vectorlike>
void print_in_order(std::vector<int> const & order,
vectorlike const & printme) {
for (int i : order)
std::cout << printme[i] << std::endl;
}
int main() {
std::vector<int> printme = {100, 200, 300};
std::vector<int> order = {2,0,1};
print_in_order(order, printme);
}
Now I have a vector<Elem> and want to print a single integer member, Elem.a, for each Elem in the vector. I could do this by creating a new vector<int> (copying a for all Elems) and pass this to the print function - however, I feel like there must be a way to pass a "virtual" vector that, when operator[] is used on it, returns this only the member a. Note that I don't want to change the print_in_order function to access the member, it should remain general.
Is this possible, maybe with a lambda expression?
Full code below.
#include <iostream>
#include <vector>
struct Elem {
int a,b;
Elem(int a, int b) : a(a),b(b) {}
};
template <typename vectorlike>
void print_in_order(std::vector<int> const & order,
vectorlike const & printme) {
for (int i : order)
std::cout << printme[i] << std::endl;
}
int main() {
std::vector<Elem> printme = {Elem(1,100), Elem(2,200), Elem(3,300)};
std::vector<int> order = {2,0,1};
// how to do this?
virtual_vector X(printme) // behaves like a std::vector<Elem.a>
print_in_order(order, X);
}
It's not really possible to directly do what you want. Instead you might want to take a hint from the standard algorithm library, for example std::for_each where you take an extra argument that is a function-like object that you call for each element. Then you could easily pass a lambda function that prints only the wanted element.
Perhaps something like
template<typename vectorlike, typename functionlike>
void print_in_order(std::vector<int> const & order,
vectorlike const & printme,
functionlike func) {
for (int i : order)
func(printme[i]);
}
Then call it like
print_in_order(order, printme, [](Elem const& elem) {
std::cout << elem.a;
});
Since C++ have function overloading you can still keep the old print_in_order function for plain vectors.
Using member pointers you can implement a proxy type that will allow you view a container of objects by substituting each object by one of it's members (see pointer to data member) or by one of it's getters (see pointer to member function). The first solution addresses only data members, the second accounts for both.
The container will necessarily need to know which container to use and which member to map, which will be provided at construction. The type of a pointer to member depends on the type of that member so it will have to be considered as an additional template argument.
template<class Container, class MemberPtr>
class virtual_vector
{
public:
virtual_vector(const Container & p_container, MemberPtr p_member_ptr) :
m_container(&p_container),
m_member(p_member_ptr)
{}
private:
const Container * m_container;
MemberPtr m_member;
};
Next, implement the operator[] operator, since you mentioned that it's how you wanted to access your elements. The syntax for dereferencing a member pointer can be surprising at first.
template<class Container, class MemberPtr>
class virtual_vector
{
public:
virtual_vector(const Container & p_container, MemberPtr p_member_ptr) :
m_container(&p_container),
m_member(p_member_ptr)
{}
// Dispatch to the right get method
auto operator[](const size_t p_index) const
{
return (*m_container)[p_index].*m_member;
}
private:
const Container * m_container;
MemberPtr m_member;
};
To use this implementation, you would write something like this :
int main() {
std::vector<Elem> printme = { Elem(1,100), Elem(2,200), Elem(3,300) };
std::vector<int> order = { 2,0,1 };
virtual_vector<decltype(printme), decltype(&Elem::a)> X(printme, &Elem::a);
print_in_order(order, X);
}
This is a bit cumbersome since there is no template argument deduction happening. So lets add a free function to deduce the template arguments.
template<class Container, class MemberPtr>
virtual_vector<Container, MemberPtr>
make_virtual_vector(const Container & p_container, MemberPtr p_member_ptr)
{
return{ p_container, p_member_ptr };
}
The usage becomes :
int main() {
std::vector<Elem> printme = { Elem(1,100), Elem(2,200), Elem(3,300) };
std::vector<int> order = { 2,0,1 };
auto X = make_virtual_vector(printme, &Elem::a);
print_in_order(order, X);
}
If you want to support member functions, it's a little bit more complicated. First, the syntax to dereference a data member pointer is slightly different from calling a function member pointer. You have to implement two versions of the operator[] and enable the correct one based on the member pointer type. Luckily the standard provides std::enable_if and std::is_member_function_pointer (both in the <type_trait> header) which allow us to do just that. The member function pointer requires you to specify the arguments to pass to the function (non in this case) and an extra set of parentheses around the expression that would evaluate to the function to call (everything before the list of arguments).
template<class Container, class MemberPtr>
class virtual_vector
{
public:
virtual_vector(const Container & p_container, MemberPtr p_member_ptr) :
m_container(&p_container),
m_member(p_member_ptr)
{}
// For mapping to a method
template<class T = MemberPtr>
auto operator[](std::enable_if_t<std::is_member_function_pointer<T>::value == true, const size_t> p_index) const
{
return ((*m_container)[p_index].*m_member)();
}
// For mapping to a member
template<class T = MemberPtr>
auto operator[](std::enable_if_t<std::is_member_function_pointer<T>::value == false, const size_t> p_index) const
{
return (*m_container)[p_index].*m_member;
}
private:
const Container * m_container;
MemberPtr m_member;
};
To test this, I've added a getter to the Elem class, for illustrative purposes.
struct Elem {
int a, b;
int foo() const { return a; }
Elem(int a, int b) : a(a), b(b) {}
};
And here is how it would be used :
int main() {
std::vector<Elem> printme = { Elem(1,100), Elem(2,200), Elem(3,300) };
std::vector<int> order = { 2,0,1 };
{ // print member
auto X = make_virtual_vector(printme, &Elem::a);
print_in_order(order, X);
}
{ // print method
auto X = make_virtual_vector(printme, &Elem::foo);
print_in_order(order, X);
}
}
You've got a choice of two data structures
struct Employee
{
std::string name;
double salary;
long payrollid;
};
std::vector<Employee> employees;
Or alternatively
struct Employees
{
std::vector<std::string> names;
std::vector<double> salaries;
std::vector<long> payrollids;
};
C++ is designed with the first option as the default. Other languages such as Javascript tend to encourage the second option.
If you want to find mean salary, option 2 is more convenient. If you want to sort the employees by salary, option 1 is easier to work with.
However you can use lamdas to partially interconvert between the two. The lambda is a trivial little function which takes an Employee and returns a salary for him - so effectively providing a flat vector of doubles we can take the mean of - or takes an index and an Employees and returns an employee, doing a little bit of trivial data reformatting.
template<class F>
struct index_fake_t{
F f;
decltype(auto) operator[](std::size_t i)const{
return f(i);
}
};
template<class F>
index_fake_t<F> index_fake( F f ){
return{std::move(f)};
}
template<class F>
auto reindexer(F f){
return [f=std::move(f)](auto&& v)mutable{
return index_fake([f=std::move(f),&v](auto i)->decltype(auto){
return v[f(i)];
});
};
}
template<class F>
auto indexer_mapper(F f){
return [f=std::move(f)](auto&& v)mutable{
return index_fake([f=std::move(f),&v](auto i)->decltype(auto){
return f(v[i]);
});
};
}
Now, print in order can be rewritten as:
template <typename vectorlike>
void print(vectorlike const & printme) {
for (auto&& x:printme)
std::cout << x << std::endl;
}
template <typename vectorlike>
void print_in_order(std::vector<int> const& reorder, vectorlike const & printme) {
print(reindexer([&](auto i){return reorder[i];})(printme));
}
and printing .a as:
print_in_order( reorder, indexer_mapper([](auto&&x){return x.a;})(printme) );
there may be some typos.
I am learning factory design pattern. I am not able to figure out how we can pass parameters to object created using Factory pattern.
One Small Silly Example:
Suppose I have three class, Class A and class B and Class Number. Number being the base class. Also, class A expects three integers and has functionality to add them and class B expects two integer and adds them
Code Snippet:
int main()
{
Factory *facObj = new Factory();
// Addition for Two Integers
Number * numberObjOne = facObj->createObj("AddThreeInteger");
Number * numberObjTwo = facObj->createObj("AddTwoInteger");
}
Factory.cpp
Number * Factory::createObj(string str)
{
if (str == "AddThreeInteger")
{
return new A(1,2,3);
}
else if (str == "AddTwoInteger")
{
return new B(1,2);
}
else
return NULL;
}
Question: Now no matter what I do I can only add the hard coded numbers. How do I pass these integers value from my Client code or from main(). Its a silly example and I am new to programming. Kindly help me here. How can I not hardcode the value and get the results. Can I somwhow pass the values at facObj->createObj Am I making sense? Kindly help me.
Complete, runnable example. c++11 or better.
Note the use of unique_ptr. Don't use raw pointers.
#include <iostream>
#include <memory>
#include <stdexcept>
#include <exception>
#include <utility>
template<class T, class...Args>
struct creatable_from {
template<class X, class...Ys>
static auto test(int) -> decltype(X(std::declval<Ys>()...), void(), std::true_type());
template<class X, class...Ys>
static auto test(...) -> decltype(std::false_type());
static constexpr auto value = decltype(test<T, Args...>(0))::value;
};
struct Operation {
virtual ~Operation() = default;
virtual int operator()() const = 0;
};
struct Add : Operation
{
Add(int x, int y)
: x(x), y(y)
{}
int operator()() const override {
return x + y;
}
int x, y;
};
struct Sub : Operation
{
Sub(int x, int y)
: x(x), y(y)
{}
int operator()() const override {
return x - y;
}
int x, y;
};
struct AddSub : Operation
{
AddSub(int x, int y, int z)
: x(x), y(y), z(z)
{}
int operator()() const override {
return x + y - z;
}
int x, y, z;
};
struct Factory
{
template<class...Args>
std::unique_ptr<Operation> create(const std::string& type, Args&&...args)
{
if (type == "Add") {
return do_create<Add>(std::forward<Args>(args)...);
}
if (type == "Sub") {
return do_create<Sub>(std::forward<Args>(args)...);
}
if (type == "AddSub") {
return do_create<AddSub>(std::forward<Args>(args)...);
}
// default - return a null pointer, but would probably be better to
// throw a logic_error
return {};
}
private:
template<class T, class...Args>
static auto do_create(Args&&...args)
-> std::enable_if_t< creatable_from<T, Args...>::value, std::unique_ptr<T> >
{
return std::make_unique<T>(std::forward<Args>(args)...);
}
template<class T, class...Args>
static auto do_create(Args&&...args)
-> std::enable_if_t< not creatable_from<T, Args...>::value, std::unique_ptr<T> >
{
throw std::invalid_argument("wrong number of arguments");
}
};
int main()
{
auto facObj = Factory();
auto t1 = facObj.create("Add", 2, 3);
auto t2 = facObj.create("Sub", 3, 2);
auto t3 = facObj.create("AddSub", 2, 3, 4);
std::cout << (*t1)() << std::endl;
std::cout << (*t2)() << std::endl;
std::cout << (*t3)() << std::endl;
}
expected output:
5
1
1
There are many ways to do it.
One way is to have separate create methods in your factory, to construct each one of your subclasses. Each create method would take the appropriate parameters for the subclass it constructs, and forwards them to the subclass's constructor, accordingly.
Another way is to have a separate "parameters" class that would define, in some way, the parameters for the created object. It would allow those parameters to be specified. For this case, a std::vector would be appopriate. Then, your create() method would have to validate that the passed parameters are valid, and throw an exception otherwise, or something along the same lines.
I am not an expert on design patterns. So I am not sure if the following suggestions are still compatible with the factory pattern.
One way could be to create different methods like CreateObjectA(int a, int b, int c) and CreateObjectB(int a, int b). Another option could be to add a std::vector<int> to your method createObj. If all classes A, B, ... differ in the number of integers, the length of the vector could be used to decide which object to create. If this is not possible you could e.g. use some sort of ID to tell the factory which object to create.
Option 1
You could generalize your factory class using templates.
For instance, you could send the type you want to construct to the factory.
This is an example for what could be possible solution for your case:
struct Factory {
template<typename T, typename... Args>
T create(Args&&... args) {
return T{1, 2, std::forward<Args>(args)...};
}
};
It will be used like this:
Factory factory;
auto myA = factory.create<A>(1, 2, "an additional char* parameter");
// no additional parameter works too
auto myB = factory.create<B>();
Well, this class is pretty simple. It construct a type T with the arguments Args, plus two int parameter. But it will not allow making a different type depending on the value of a string though.
Btw you should replace every new in your code by std::make_unique, there where a lot of memory leaks in your code. Alternatively, you can create objects of the stack.
Option 2
If you know what type to construct depending on the parameters you send, you could just overload your function.
Here's what it would look like:
struct Factory {
A create(int a, int b, int c) {
return A{a, b, c};
}
B create(int a, int b) {
return B{a, b};
}
};
You could use it like this:
Factory factory;
auto myA = factory.create(1, 2, 3);
auto myB = factory.create(1, 2);
This might be easier to implement. But take note that you will not be able to have a class with two constructor neither you won't be able to have two class with the same parameters.
Say a class Foo has two dependencies (Bar and Baz), and that it is an error to construct a Foo without providing both of them. Constructor injection makes it easy to guarantee at compile time that this is done:
class Foo
{
public:
Foo(const std::shared_ptr<Bar>& bar, const std::shared_ptr<Baz>& baz);
// (don't get hung up on the type of pointer used; it's for example only)
};
But let's say Foo also needs two doubles:
class Foo
{
public:
Foo(const std::shared_ptr<Bar>& bar, const std::shared_ptr<Baz>& baz,
double val1, double val2);
};
Now there is a problem; it would be really easy for the caller to accidentally transpose val1 and val2 and create a runtime bug. We can add a Params struct to allow named initialization and preclude this:
class Foo
{
public:
struct Params
{
std::shared_ptr<Bar> bar;
std::shared_ptr<Baz> baz;
double val1;
double val2
};
Foo(const Params& params);
};
// ...
std::shared_ptr<Foo> MakeDefaultFoo()
{
Foo::Params p;
p.bar = std::make_shared<Bar>();
p.baz = std::make_shared<Baz>();
p.val1 = 4.0;
p.val2 = 3.0;
return std::make_shared<Foo>(p);
}
But now we have the problem that the caller might forget to populate one of the fields in Params, which would not be detectable until runtime. struct initialization syntax or an initializer list would make it impossible to forget a field, but then we're back to relying on position!
Is there some trick that makes it possible to have the best of both worlds--compiler-enforced mandatory arguments that are assigned by name instead of position?
Just have a simple wrapper may work:
template <typename Tag, typename T>
struct Argument {
explicit Argument( const T &val );
T get() const;
};
class Foo {
public:
struct Val1Tag;
struct Val2Tag;
typedef Argument<Val1Tag,double> Val1;
typedef Argument<Val2Tag,double> Val2;
Foo( Val1 v1, Val2 v2 );
};
Foo foo( Foo::Val1( 1.0 ), Foo::Val2( 2.3 ) );
Now types are explicit and you cannot swap them without getting compiler error.
Very curious to see what cdhowie is tinkering with, but in the meantime, a simple wrapper with different types might solve some problems:
struct Val1 {
explicit Val1(double v) : v(v) { }
operator double() const { return v; }
double v;
};
// copy for Val2
class Foo
{
public:
Foo(const std::shared_ptr<Bar>& bar, const std::shared_ptr<Baz>& baz,
Val1 val1, Val2 val2);
};
This way you can't mix them up, since you'll have to construct a Foo like:
Foo foo(bar, baz, Val1{3.0}, Val2{7.0});
It's a bunch of extra typing to make sure the types are different, and you definitely have to make sure you make the constructor explicit (or it defeats the point), but it helps.
Something like this (untested)
template <typename tag, typename t>
struct param
{
explicit param(t vv)
: v(vv) {}
param(const param& p)
: v(p.v) {}
t v;
};
struct one{}; struct two {};
using paramone = param<one, double>;
using paramtwo = param<two, double>;
void somefunc (paramone p1, paramtwo p2)
{ ... };
void somefunc (paramtwo p2, paramone p1)
{ somefunc(p1, p2); }
// using it
somefunc (2, 3); // bad
somefunc (paramone(2), paramtwo(3)); // good
somefunc (paramtwo(3), paramone(2)); // also good
Is it possible to "pass" somehow a static initializer list at construction time to a container wrapper class that than in turn initializes its member?
struct bar {
bar(void * ptr): ptr(ptr) {}
void * ptr;
};
template<class T, int N>
struct foo
{
foo( args ) :store(args) {} // here the arg list should be passed
T store[N];
};
int main()
{
bar b[2]={NULL,NULL};
foo<bar,2> f(NULL,NULL); // This should be possible
}
Unfortunately I cannot use STL or Boost.
Let me just explain, if you doubt the usefulness of this. First, this is a very "cooked-down" setup. Explaining the whole setup is not adequate to post here nor would it help. Just imagine a case, where you have a nested expression template tree, you traverse it at compile-time and collect the involved objects and store them in a container wrapper like the above. If you have further question please ask.
Edited: The default constructor of T should not be called.
Method 1: va_args
If you agree to make bar POD this can be done with va_args:
#include <stdarg.h>
struct bar {
void * ptr;
};
template<class T, int N>
struct foo
{
foo(...) { // here the arg list should be passed
va_list ap;
va_start(ap, N);
for (int i = 0; i < N; ++i) {
store[i] = va_arg(ap, T);
}
va_end(ap);
}
T store[N];
};
int main()
{
foo<bar,2> f(bar(),bar());
}
It's not great though - you have to trust the caller a little too much for my liking and the POD requirement could be quite limiting.
Method 2: range
If you agree to make your type T both default constructable and assignable you can use this method:
#include <assert.h>
#include <stdlib.h>
struct bar {
bar(void * ptr): ptr(ptr) {}
bar() {}
void * ptr;
};
template<class T, int N>
struct foo
{
foo(T *begin, const T *end) { // here the arg list should be passed
// Normally I'd use std::copy here!
int i = 0;
while (begin != end) {
assert(i < N);
store[i] = *begin++;
}
}
T store[N];
};
int main()
{
bar b[2]={NULL,NULL};
foo<bar,2> f(&b[0], &b[sizeof(b)/sizeof(bar)]);
}
It's not quite seamless - you end up with both an array and an instance of your object, but you can make the array static const and kept well hidden from the rest of the code at least.
Method 3: operator overloading tricks
You could also use a trick with operator, to reduce all of the items into one parameter, which IIRC is similar to what Boost.Assign does.
With C++11, we get lambdas, and the possibility to create functions/functors/closures on-the-fly where we actually need them, not somewhere where they don't really belong.
In C++98/03, a nice way to make function-local functors/closures would've been the following:
struct{
void operator()(int& item){ ++item; }
}foo_functor;
some_templated_func(some_args, foo_functor);
Sadly, you can't use local types for templates (Visual Studio allows this with language extensions enabled). My train of though then went the following way:
struct X{
static void functor(int& item){ ++item; }
};
some_templated_func(some_args, &X::functor);
The obvious problem being, that you can't save any state, since local structs/classes can't have static members.
My next thought to solving that problem was using a mix of std::bind1st and std::mem_fun and non-static methods & variables, but unfortunately std::mem_fun somehow chokes with std::mem_fn(&X::functor), which again might be because local struct/classes can't be used in templates:
// wanted, not working solution
struct X{
int n_;
X(int n) : n_(n) {}
void functor(int& item) const { item += n_; }
};
X x(5);
some_templated_func(some_args,std::bind1st(std::mem_fun(&X::functor),&x));
Fails under VC9 & VC10 (with /Za, disabled language extensions) with the following error
error C2893: Failed to specialize function template 'std::const_mem_fun1_t<_Result,_Ty,_Arg> std::mem_fun(_Result (_Ty::* )(_Arg) const)'
With the following template arguments:
'void'
'main::X'
'int &'
Or under gcc 4.3.4 with this error
error: no matching function for call to ‘mem_fun(void (main()::X::*)(int&))’
Funnily enough, VC9 / VC10 still chokes on the above example, even with language extensions enables:
error C2535: 'void std::binder1st<_Fn2>::operator ()(int &) const' : member function already defined or declared
So, is the functionality stated in the title somehow, anyhow achievable? Or am I making a mistake in the last example in how I use std::bind1st or std::mem_fun?
bind1st only works for binary functions, and in general it's very restricted. mem_fn works with non-static member functions only; for your application you would want ptr_fun.
Really the best tool for the job in C++03 is Boost Bind, or I'll demonstrate here with tr1::bind which is (in my opinion) more portable.
#include <tr1/functional>
#include <iostream>
#include <algorithm>
using namespace std::tr1::placeholders;
int nums[] = { 1, 2, 4, 5, 6, 8 };
int main() {
struct is_multiple {
static bool fn( int mod, int num ) { return num % mod == 0; }
};
int *n = std::find_if( nums, nums + sizeof nums/sizeof*nums,
std::tr1::bind( is_multiple::fn, 3, _1 ) );
std::cout << n - nums << '\n';
}
Yes you can, but you'll have to implement one or more virtual methods declared in an interface.
template<typename Arg, typename Result>
struct my_unary_function
{
virtual Result operator()(Arg) = 0;
};
template<typename Arg, typename Result>
struct my_unary_functor
{
my_unary_function<Arg, Result> m_closure;
my_unary_functor(my_unary_function<Arg, Result> closure) : m_closure(closure) {}
Result operator()(Arg a) { return m_closure(a); }
};
template<typename T, TFunctor>
void some_templated_function( std::vector<T> items, TFunctor actor );
Then you can define and use a local closure:
void f()
{
std::vector<int> collection;
struct closure : my_unary_function<int, int>
{
int m_x, m_y;
closure(int x, int y) : m_x(x), m_y(y) {}
virtual int operator()(int i) const { cout << m_x + m_y*i << "\t"; return (m_x - m_y) * i; }
};
some_templated_function( collection, my_unary_functor<int,int>(closure(1, 5)) );
}
Credit to #Omnifarious for this improvement (my_unary_functor not needed):
void f()
{
std::vector<int> collection;
struct closure : my_unary_function<int, int>
{
int m_x, m_y;
closure(int x, int y) : m_x(x), m_y(y) {}
virtual int operator()(int i) const { cout << m_x + m_y*i << "\t"; return (m_x - m_y) * i; }
};
// need a const reference here, to bind to a temporary
const my_unary_functor<int,int>& closure_1_5 = my_unary_functor<int,int>(closure(1, 5))
some_templated_function( collection, closure_1_5 );
}
If this was doable in C++03, why would C++0x have introduced lambdas? There's a reason lambdas exist, and it's because binding and all the other C++03 solutions suck hideously.