Is it possible to create a functor with multiple constructors? I want to be able to use the functor in various ways, initializing its various members in different ways, all depending upon which constructor is used to set it up initially.
But is there a more elegant solution than the one I propose here using functors with multiple constructors?
This added level of reuse would play very well in the communications wire protocol interpreter I am writing. A particular wire (or a subset of wires) in a communications line can often serve different purposes, depending upon the specific protocol in use. I'd thus like to be able to create a small set of functors that can be adaptable, within reasonable parameters, rather than having to create a large set of very specific functors, each of which has comparatively little adaptability.
The smaller set of highly-adaptable functors would then be used, one at a time, as a parameter to a template function in another class, which function can either read or write data according to the "rules" embodied within the functor parameter used to call that template function.
My aim is to make the code as generic as possible, to allow many different permutations of protocols and sub-protocols to be used with the same basic code.
I'm not sure I understand your question. A straight answer is: yes you can, you can even overload the operator().
class MyFunctor {
public:
MyFunctor(int a) : a(a), b(0.0) {}
MyFunctor(double b) : a(0), b(b) {}
int operator()(int c) const { return a + c; }
double operator()(double c) const { return b + c; }
private:
int a;
double b;
};
MyFunctor fromInt(2);
MyFunctor fromDouble(2.1);
std::cout << fromInt(3) << std::endl; // Print 5
std::cout << fromInt(3.1) << std::endl; // Print 3.1
std::cout << fromDouble(2) << std::endl; // Print 2
std::cout << fromDouble(2.2) << std::endl; // Print 4.3
However, I feel this violate the Single responsibility principle. A better solution might be to create several small functors and choose the best one using a factory.
class MyFunctorInt {
public:
MyFunctorInt(int a) : a(a) {}
int operator()(int c) const { return a + c; }
private:
int a;
};
class MyFunctorDouble {
public:
MyFunctorDouble(double b) : b(b) {}
double operator()(double c) const { return b + c; }
private:
double b;
};
MyFunctorInt createFunctor(int a)
{ return MyFunctorInt(a); }
MyFunctorDouble createFunctor(double b)
{ return MyFunctorDouble(b); }
template<class Callable, class Real>
void myGenericFunction(const Callable &f, Real a)
{ std::cout << f(a) << std::endl; }
myGenericFunction(createFunctor(2),3); // Print 5
myGenericFunction(createFunctor(2.2),3); // Print 5.2
This probably scales better, since if you want to add a new capability to your code, e.g. for strings, you can just create a new file in which there is a new class MyFunctorString and a new overload to createFunctor(std::string). You can easily unit-test this new class, and you do not have to worry about interactions between various overloads. For instance, the first time I wrote the code for MyFunctor, I forgot to initialise all the members to 0, which lead to undefined results.
Related
My solution I gonna use to add “C++ Extension Methods” to JNI jobjects to make NDK code more readable like (Uniform Function Call Syntax) is:
Subclass the class that I want to add extension methods.
For invoking the “Extension Methods” make a pointer of type ExtensionsClass to point to OriginalClass - (Although the pointed object is’nt an ExtensionsClass).
The overload is minimal & we can access public methods of the Original class.
#include <iostream>
// Represents a class external to my source
class Person {
public:
Person(){
privateage = 20;
}
int age() { return privateage; }
private:
int privateage;
short anotherField;
};
class PersonExtensions : private Person {
public:
inline int size() { return 5 + age(); }
//NoFieldsOnExtensionClass
};
int main() {
Person person;
PersonExtensions* pE = (PersonExtensions*) &person;
std::cout << pE -> size() << std::endl;
std::cout << (*pE).size() << std::endl;
std::cout << sizeof(Person) << std::endl;
std::cout << sizeof(PersonExtensions) << std::endl;
return 0;
}
Do you think that this incorrect pointer assignment, since “Extension Method” only accessed public members of extended class & extension class don’t going to have any Field variables, can represent a problem in the future?
The size of the object are the same.
Thanks a lot.
This is undefined behaviour.
Yes that can break at any point.
Consider overloading ->* or something instead.
Or just using a free function.
If you really want infix notation:
template<class T, class F>
struct extension_method_t {
F f;
friend auto operator->*( T& t, extension_method_t const& self ) {
return [&t,&self](auto&&...args)->decltype(auto) {
return self.f( t, decltype(args)(args)... );
};
}
};
template< class T, class F >
extension_method_t<T,F> extension_method( F f ) {
return {std::move(f)};
}
then:
auto size = extension_method<Person>([](auto& person)->int{
return 5+person.age();
});
Person p;
std::cout << (p->*size)() << "\n"; // prints p.age()+5
here we don't have an extension method, but we do have an extension method pointer.
What you are doing in your question code is Undefined Behavior, so an especially an optimizing compiler might do really "fun" things with it. In other words, don't do it, it might break at any time even if it works when you test it. Only way to make sure it would actually work would be to examine the produced assembly code after each compilation to make sure it does what you want, and this is essentially impossible, so it is never safe.
You are using private inheritance. So for same effect you can just do this:
class PersonExtensions {
public:
PersonExtensions(Person *person) : _person(person) {}
inline int size() { return 5 + _person->age(); }
private:
Person *_person;
};
If you instead used public inheritance (so you could just call Person methods through PersonExtensions), then you'd need to add a getter for _person (for cases where real Person is needed), and/or add delegates for Person methods (for so called static polymorphism).
I would like to know if copying an object in the following manner is acceptable vis-a-vis copying the individual elements.
#include <iostream>
using namespace std;
class abc{
public:
abc(int a = 10, int b = 5);
abc(const abc &obj, int b = 10);
int ret_x() { return x; }
int ret_y() { return y; }
private:
int x;
int y;
};
abc::abc(int a, int b)
: x(a),
y(b)
{
}
abc::abc(const abc &obj, int b)
{
if (this != &obj) {
*this = obj; -----> Copying the object
}
y = b;
}
int main()
{
abc a1;
cout << "A1 values: " << a1.ret_x() << "\t" << a1.ret_y() << endl;
abc a2(a1, 20);
cout << "A2 values: " << a2.ret_x() << "\t" << a2.ret_y() << endl;
return 0;
}
Edit:
Use case:
The issue is that object a1 is auto-generated and hence any newly introduced members in the class could not be updated. I could provide a member function to update the new members, sure, but wanted to explore this option.
The code works fine, but is the method correct?
Thanks!
As chris noted already in the comments, you are creating a completely new object. How would you want to get this passed into the constructor? Well, actually, you could perhaps via placement new:
abc a;
abc* b = new(&a)abc(a);
But this is a such an exotic case that I would not consider it, I even dare to claim someone using advanced stuff such as placement new should know what he is doing... So leave out the if-check.
In your special case, it seems OK, as no data exists that might require deep copying. Be aware, though, that you are assigning the member b twice. Not really critical with int, but on larger objects (std::string, std::vector, ...) which do deep copies this gets more and more questionable.
With C++11, though, I would prefer constructor delegation:
abc::abc(const abc& obj, int b)
: abc(obj) // copying here
{
y = b;
}
This does not solve, however, the double assignment problem. To be honest, this might not always be a true problem, in many cases the compiler might optimise the first assignment away (especially in the int case of our example). But on more complex data types (possibly already std::string), I wouldn't feel comfortable relying on the compiler detecting obsolete assignment...
Be aware that you might get into trouble if you have resources managed internally:
struct abc
{
int* array;
abc() : array(new int[7]) { }
~abc()
{
delete[] array;
}
}
Not providing an appropriate assignment operator or copy constructor – depending on the implementation variant, yours (assignment) or mine (constructor delegation) – doing the necessary deep copy will result in multiple deletion of the same data (undefined behaviour!). Following the rule of three (or more recently, rule of five), you most probably will need both anyway. You might consider the copy and swap idiom idiom then.
Finally a trick to avoid double assignment:
abc(abc const& other)
: abc(other, other.y)
{ }
abc(abc const& other, int y)
: x(other.x), y(y)
{ }
I have two functions that do the same thing: they add two numbers. One adds two numbers which are members of the class, the other adds numbers given by the user, outside the class.
Is there any way to write one single function that adds two numbers and checks whether the arguments are user input or class members?
void myclass::add(){
cout<<this->a+this->b;
}
void myclass::add(int a,int b){
cout<<a+b;
}
While you cannot really do it in a single function the common approach would be to write the more flexible of the two and use the other one just as a dispatcher:
void myclass::add(int a, int b) {
std::cout << (a+b);
}
void myclass::add() {
add(a,b);
}
Now, there are a different number of smells in this code... a function name reused to act on members or only inputs is one (a function that does not touch the object's state already smells at it not being a member, or being a static one). Printing inside a function called add (should it not return the values?)...
Disclaimer : I don't encourage such coding.
Ok, here's a method
void myClass::Add(int& a, int& b)
{
if (&a==&this->a)
{
std::cout << this->a + this->b
} else {
std::cout << a+b;
}
}
Ofc , things like myClass->Add(10,4) won't work... you will need some stack variables to hold the 10 and 4 variables.
So you want a single function that can have two different parameters? It isn't possible.
void myclass::add(int a, int b)
{
cout << a + b << endl;
}
Is what you want; but you can overload the function:
void myclass::add()
{
cout << memberA + memberB << endl;
}
In my opinion, this is a much better solution than having a single function that checks whether the variables are members or not; it makes your code readable. Don't be afraid to overload functions - it's one of those things that makes C++ awesome. I've created a class to demonstrate this:
class myClass
{
public:
myClass() : memberA(0), memberB(0) {}
~myClass() {}
void setNumbers(int a, int b)
{
memberA = a;
memberB = b;
}
void add(int a, int b)
{
cout << a + b << endl;
}
void add()
{
cout << memberA + memberB << endl;
}
private:
int memberA;
int memberB;
};
int main()
{
myClass m;
m.setNumbers(1, 2);
m.add();
return 0;
}
I've tested the add function with and without parameters and they both output the same result. The former because I used a setNumbers(..) function. Effectively, your first scenario of having two functions is the most apt solution to begin with.
In you realy wanted a single function, the way to do it is with optional default parameters.
Your declaration will be
void add(optional<int> a = optional<int>(), optional<int> b = optional<int>() );
Then in your implementation:
a ? a.get() : this->a
A benefit of this approach is that you can mix members and parameters. For example:
obj.add(1);
obj.add(optional<int>(), 2);
What is the problem with this code ? this code is giving me lots of syntax errors. Also I would like to know why functors are used in C++.
class f
{
public:
int operator(int a) {return a;}
} obj;
int main()
{
cout << obj(0) << endl;
}
You're missing an extra pair of parenthesis when declaring operator(). The name of the function is operator(), and it still needs the list of parameters after it. Thus it should look like:
int operator()(int a) {return a;}
Function objects (a.k.a. functors) like this are typically used where you'd use a pointer to a function. However, they have the advantage that they can use inheritance and they encapsulate state as well. Often, well designed class or function templates will be able to use them almost interchangeably with function pointers. However, a good optimizer can typically produce better code when a template object is used.
For a fairly sophisticated example of how you might use function objects, have a look at expression templates.
Here's a small, somewhat contrived example of how they can use inheritance:
struct unary_int_func {
virtual int operator()(int i) = 0;
};
struct negate : public unary_int_func {
int operator()(int i) {return -i;}
};
struct one_plus : public unary_int_func {
int operator()(int i) {return i+1;}
};
void show_it(unary_int_func &op, int v) {
cout << op(v) << endl;
}
In this case, we create a base class with the operator as a pure virtual function. Then we derive to concrete classes that implement it. Code such as show_it() can then use any instance of a class derived from this base. While we could just have used a pointer to a function that takes an int and returns an int, this is more typesafe. Code that uses the function pointer would accept any such function pointer, whereas this way we can define a whole new hierarchy that maps an int to an int:
struct a_different_base_class {
virtual int operator()(int i) = 0;
};
but instances of this would not be interchangeable with instances of unary_int_func.
As for state, consider a running sum function:
struct running_sum : public unary_int_func {
int total;
running_sum() : total(0) {}
int operator()(int i) {return total += i;}
};
int main()
{
running_sum s;
cout << s(1) << endl;
cout << s(2) << endl;
cout << s(3) << endl;
cout << s(4) << endl;
}
Here, the instance of running_sum keeps track of the total. It will print out 1, 3, 6 and 10. Pointers to functions have no such way of keeping state between distinct invocations. SGI's STL page on function objects has a similar example to my running sum one, but shows how you can easily apply it to a range of elements in a container.
Functors are basically functions with states. Their biggest usage is in STL and Boost libraries. For example std::sort takes a type of functor called Comparator. In this context, perhaps a function object could have been passed instead but functor offers more flexibility by means of the data members you can have and manipulate with subsequent calls to the same functor. Functors are also used to implement C++ callbacks.
As you already have figured out the issue in your operator overloading code, I would rather try to address your doubt regarding functors.
Functor is a short for 'function pointer'.
These are widely used to provide a handle to customize the behavior of an algorithm, for example the sorting algorithms in STL use functor as parameter and the user (programmer) can implement the function to tell the algorithm the result of comparison for 2 elements.
because int operator(int) is effectively equal to int int #something_missing_here#(int)
operator is a reserved keyword and not qualifier as valid function identifier/name when used alone.
I would say it is used to make compiler understand that given expression are function declaration despite the invalid identifiers used (c++ only allow alphabet and underscore as first character in naming)
A functor is an object (instance of class or struct) that typically overloads the operator(). The difference between a functor and a normal function is that because a functor is an object, it can maintain state between calls.
Because a functor is an object, rules of inheritance apply as well and you can use this to your advantage.
A functor is also useful when you use the STL. std::sort, std::for_each, etc allow you to process the contents of an entire container (arrays included). Here's an example from cplusplus.com:
// for_each example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void myfunction (int i) {
cout << " " << i;
}
struct myclass {
void operator() (int i) {cout << " " << i;}
} myobject;
int main () {
vector<int> myvector;
myvector.push_back(10);
myvector.push_back(20);
myvector.push_back(30);
cout << "myvector contains:";
for_each (myvector.begin(), myvector.end(), myfunction);
// or:
cout << "\nmyvector contains:";
for_each (myvector.begin(), myvector.end(), myobject);
cout << endl;
return 0;
}
Try this:
class f
{
public:
int operator(int a) {return a;}
};
int main()
{
f obj;
cout<<obj(0)<<endl;
}
Is there a way to make a non-resizeable vector/array of non-reassignable but mutable members? The closest thing I can imagine is using a vector<T *> const copy constructed from a temporary, but since I know at initialization how many of and exactly what I want, I'd much rather have a block of objects than pointers. Is anything like what is shown below possible with std::vector or some more obscure boost, etc., template?
// Struct making vec<A> that cannot be resized or have contents reassigned.
struct B {
vector<A> va_; // <-- unknown modifiers or different template needed here
vector<A> va2_;
// All vector contents initialized on construction.
Foo(size_t n_foo) : va_(n_foo), va2_(5) { }
// Things I'd like allowed: altering contents, const_iterator and read access.
good_actions(size_t idx, int val) {
va_[idx].set(val);
cout << "vector<A> info - " << " size: " << va_.size() << ", max: "
<< va_.max_size() << ", capacity: " << va_.capacity() << ", empty?: "
<< va_.empty() << endl;
if (!va_.empty()) {
cout << "First (old): " << va_[0].get() << ", resetting ..." << endl;
va_[0].set(0);
}
int max = 0;
for (vector<A>::const_iterator i = va_.begin(); i != va_.end(); ++i) {
int n = i->get();
if (n > max) { max = n; }
if (n < 0) { i->set(0); }
}
cout << "Max : " << max << "." << endl;
}
// Everything here should fail at compile.
bad_actions(size_t idx, int val) {
va_[0] = va2_[0];
va_.at(1) = va2_.at(3);
va_.swap(va2_);
va_.erase(va_.begin());
va_.insert(va_.end(), va2_[0]);
va_.resize(1);
va_.clear();
// also: assign, reserve, push, pop, ..
}
};
There is an issue with your requirements. But first let's tackle the fixed size issue, it's called std::tr1::array<class T, size_t N> (if you know the size at compile time).
If you don't know it at compile time, you can still use some proxy class over a vector.
template <class T>
class MyVector
{
public:
explicit MyVector(size_t const n, T const& t = T()): mVector(n,t) {}
// Declare the methods you want here
// and just forward to mVector most of the time ;)
private:
std::vector<T> mVector;
};
However, what is the point of not being assignable if you are mutable ? There is nothing preventing the user to do the heavy work:
class Type
{
public:
int a() const { return a; }
void a(int i) { a = i; }
int b() const { return b; }
void b(int i) { b = i; }
private:
Type& operator=(Type const&);
int a, b;
};
Nothing prevents me from doing:
void assign(Type& lhs, Type const& rhs)
{
lhs.a(rhs.a());
lhs.b(rhs.b());
}
I just want to hit you on the head for complicating my life...
Perhaps could you describe more precisely what you want to do, do you wish to restrict the subset of possible operations on your class (some variables should not be possible to modify, but other could) ?
In this case, you could once again use a Proxy class
class Proxy
{
public:
// WARN: syntax is screwed, but `vector` requires a model
// of the Assignable concept so this operation NEED be defined...
Proxy& operator=(Proxy const& rhs)
{
mType.a = rhs.mType.a;
// mType.b is unchanged
return *this;
}
int a() const { return mType.a(); }
void a(int i) { mType.a(i); }
int b() const { return mType.b(); }
private:
Type mType;
};
There is not much you cannot do with suitable proxies. That's perhaps the most useful pattern I have ever seen.
What you're asking is not really possible.
The only way to prevent something from being assigned is to define the operator = for that type as private. (As an extension of this, since const operator = methods don't make much sense (and are thus uncommon) you can come close to this by only allowing access to const references from your container. But the user can still define a const operator =, and you want mutable objects anyways.)
If you think about it, std::vector::operator [] returns a reference to the value it contains. Using the assignment operator will call operator = for the value. std::vector is completely bypassed here (except for the operator[] call used to get the reference in the first place) so there is no possibility for it (std::vector) to in any way to override the call to the operator = function.
Anything you do to directly access the members of an object in the container is going to have to return a reference to the object, which can then be used to call the object's operator =. So, there is no way a container can prevent objects inside of it from being assigned unless the container implements a proxy for the objects it contains which has a private assignment operator that does nothing and forwards other calls to the "real" object, but does not allow direct access to the real object (though if it made sense to do so, you could return copies of the real object).
Could you create a class which holds a reference to your object, but its constructors are only accessible to its std::vector's friend?
e.g.:
template<typename T>
class MyRef {
firend class std::vector< MyRef<T> >
public:
T& operator->();
[...etc...]
You can achieve what you want by making the std::vector const, and the vector's struct or class data mutable. Your set method would have to be const. Here's an example that works as expected with g++:
#include <vector>
class foo
{
public:
foo () : n_ () {}
void set(int n) const { n_ = n; }
private:
mutable int n_;
};
int main()
{
std::vector<foo> const a(3); // Notice the "const".
std::vector<foo> b(1);
// Executes!
a[0].set(1);
// Failes to compile!
a.swap(b);
}
That way you can't alter the vector in any way but you can modify the mutable data members of the objects held by the vector. Here's how this example compiles:
g++ foo.cpp
foo.cpp: In function 'int main()':
foo.cpp:24: error: passing 'const std::vector<foo, std::allocator<foo> >' as 'this' argument of 'void std::vector<_Tp, _Alloc>::swap(std::vector<_Tp, _Alloc>&) [with _Tp = foo, _Alloc = std::allocator<foo>]' discards qualifiers
The one disadvantage I can think of is that you'll have to be more aware of the const-correctness of your code, but that's not necessarily a disadvantage either.
HTH!
EDIT / Clarification: The goal of this approach is not defeat const completely. Rather, the goal is to demonstrate a means of achieving the requirements set forth in the OP's question using standard C++ and the STL. It is not the ideal solution since it exposes a const method that allows alteration of the internal state visible to the user. Certainly that is a problem with this approach.