What is this operator overloading function overloading? - c++

I am looking through the CMBC source code and came across this code snippet:
void goto_symext::operator()(const goto_functionst &goto_functions)
{
goto_functionst::function_mapt::const_iterator it=
goto_functions.function_map.find(goto_functionst::entry_point());
if(it==goto_functions.function_map.end())
throw "the program has no entry point";
const goto_programt &body=it->second.body;
operator()(goto_functions, body);
}
I have never seen a operator()(args) syntax before and googling does not seem to yield anything.

As answered in the comments, /*return type*/ operator()(/*params*/) is the syntax for overloading the () operator.
struct Foo { void operator()() { std::cout << "Hello, world!"; } };
Foo f;
f(); //Hello, world!

That would be the function call operator, which allows you to make function-like objects.
struct Functor {
bool operator()(int a, int b = 3);
};
bool Functor::operator()(int a, int b /* = 3 */) {
if ((a > (2 * b)) || (b > (2 * a))) {
return true;
} else {
return false;
}
}
// ...
Functor f;
bool b = f(5); // Calls f.operator()(5, 3).
bool c = f(3, 5);
It has the benefits that you can save state information in the function-like object's fields, and that if necessary, you can hide overloaded versions of the operator within the object instead of leaving them exposed.
class Functor {
int compareTo;
public:
Functor(int cT);
bool operator()(int a);
bool operator()(char c);
};
Functor::Functor(int cT) : compareTo(cT) { }
bool Functor::operator()(int a) {
if ((a > (2 * compareTo)) || (compareTo > (2 * a))) {
return true;
} else {
return false;
}
}
bool Functor::operator()(char c) { return false; }
It can be used to make it easier to write code that can accept any function instead of depending on function pointers. [It works especially well when used in tandem with templates, in this regard.]
See here or here for more information.

Related

Call an inline friend from a method instead of itself

struct P {
int x, y;
friend P operator-(P u, P v) { return {u.x - v.x, u.y - v.y}; }
friend int cross(P u, P v) { return u.x * v.y - u.y * v.x; }
int cross(P u, P v) const { return cross(u - *this, v - *this); }
};
The method is an infinite loop (it will call itself instead of the friend).
Is there any way to get around this issue without changing the interface (the names)?
It is possible with a declaration inside the member function:
#include <stdio.h>
struct Foo {
friend int add(int a, int b) {
return a + b;
}
int add(int a, int b) const {
int add(int, int); // function declaration
return add(a, b); // call that declared function
}
};
int main() {
Foo foo;
printf("%d", foo.add(1, 2)); // prints 3
}
Demo
You can't have two member functions with the same name and the same signature in a struct (or class).
One solution is to move the friend function out of the struct, so that it can be referred to with a global namespace specifier ::
#include <iostream>
int cross(int i) { return 42; }
struct P {
friend int cross(int i);
int cross(int i) const { return ::cross(i - 1); }
};
int main() {
P p = {};
std::cout << p.cross(7) << std::endl;
}
The original code produced two warnings, very descriptive:
1 > 1.cpp(6, 25) : warning C4514 : 'cross' : unreferenced inline function has been removed
1 > 1.cpp(7) : warning C4717 : 'P::cross' : recursive on all control paths, function will cause runtime stack overflow
Re: without changing the interface (the names) - you could simply rename your friend function and even make it private; it is not a part of the interface.
Ayxan Haqverdili's answer seems to be cleanest possible, and abides by the ISO. However, pre-gcc 11.0 and pre-clang 8.0 appear to have bugs that cause this to fail.
Luckily in this case there's an alternative that uses argument-dependent lookup:
#include <iostream>
class Foo
{
friend int Bar (Foo)
{
return 13;
}
friend int RedirectToBar (Foo);
public:
int Bar (Foo)
{
return RedirectToBar(Foo());
}
};
int RedirectToBar (Foo)
{
return Bar(Foo());
}
int main ()
{
std::cout << Foo().Bar(Foo()) << std::endl;
}
Live demo
Keep in mind that this only works because some of the arguments to the function are an associated class.
If that's not the case and you really want to keep this design and really need compatibility with older compilers, then we can add in a dummy associated class without breaking the interface by adding it as a default parameter:
#include <iostream>
int RedirectToBar ();
class Foo
{
struct Key {};
friend int Bar (Key = Key())
{
return 13;
}
friend int RedirectToBar ();
public:
int Bar ()
{
return RedirectToBar();
}
};
int RedirectToBar ()
{
return Bar(Foo::Key());
}
int main ()
{
std::cout << Foo().Bar() << std::endl;
}
Live demo
However, it's important to add that all of this is a big code smell. Although I don't know the real-world problem of the OP, this seems like a terrible hack to get around bad design choices.
I ended up using this solution similar to Peter's and Yksisarvinen's:
struct P {
int x, y;
friend P operator-(P u, P v) { return P{u.x - v.x, u.y - v.y}; }
friend int cross(P u, P v);
int cross(P u, P v) const;
};
int cross(P u, P v) { return u.x * v.y - u.y * v.x; }
int P::cross(P u, P v) const { return ::cross(u - *this, v - *this); }
Not quite sure yet why the compiler doesn't find ::cross if I write it inside of P.
Note, there is one potential drawback: we have to specify the return type of both functions (can't have it deduced with auto), but this was not needed in this case.

'const' keyword changing semantics

I attempted today's leetcode challenge in C++. You have to find cousins in a binary tree. Here's my code.
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
class Solution {
public:
bool isCousins(TreeNode* root, int x, int y) {
this->x = x;
this->y = y;
return visit(overloaded{
[](const bool& r) {
return r;
},
[](const optional<int>& r) {
return false;
}
}, helper(root));
}
private:
int x;
int y;
variant<const bool, optional<int>> helper(TreeNode* node) {
if (node == nullptr) {
return variant<const bool, optional<int>>((optional<int>()));
}
else if (node->val == x) {
return variant<const bool, optional<int>>(optional<int>(0));
}
else if (node->val == y) {
return variant<const bool, optional<int>>(optional<int>(0));
}
else {
auto l = helper(node -> left);
auto r = helper(node -> right);
return visit(overloaded{
[](const bool& l, optional<int>& r) {
assert(!r.has_value());
return variant<const bool, optional<int>>(l);
},
[](optional<int>& l, const bool& r) {
assert(!l.has_value());
return variant<const bool, optional<int>>(r);
},
[](optional<int> l, optional<int> r) {
if (l.has_value() && r.has_value()) {
return variant<const bool, optional<int>>(*l > 0 && *l == *r);
}
else if (l.has_value()) {
++*l;
return variant<const bool, optional<int>>(l);
}
else if (r.has_value()) {
++*r;
return variant<const bool, optional<int>>(r);
}
else {
return variant<const bool, optional<int>>((optional<int>()));
}
}
}, l, r);
}
}
};
A testcase that demonstrates my issue is
[1,3,2,null,null,7,4,null,null,5,6,null,8,null,9]
8
9
The code above runs and completes successfully. However, if I remove a single const keyword in line 10 ([](bool& r) {) then it returns a different (incorrect) answer. const is for compile-time safety, so shouldn't affect semantics, but I guess something strange is happening with const overloading? What's going on exactly?
Possibly related: it also breaks my mental model that if, instead of declaring l, rin lines 34,35, I pass them directly as arguments to visit (ie. return visit(overloaded{..}, helper(node->left), helper(node->right)), it also fails. I would again expect that to have no effect on semantics.
Removing the const in this case changes the meaning of the code, by changing which function is selected in overload resolution.
Consider the following overload set and call:
void f(int const &) { std::cout << "i"; }
void f(bool) { std::cout << "b"; }
int main()
{
int const i = 42;
f(i); // prints i
f(42); // prints i
}
both call the first function (as expected), because a int const & binds to a int const, as well as int&& (a temporary int).
However, if we remove the const in the first function of the overload set, and make the same call:
void f(int &) { std::cout << "i"; }
void f(bool) { std::cout << "b"; }
int main()
{
int const i = 42;
f(i); // prints b
f(42); // prints b
}
the first function is not selected, because an int &, cannot bind to a int const. However, a bool can bind to an int const, (after an implicit conversion), and it calls the second function. Similarly, an int & cannot bind to a int&&, but a bool can, so it calls the second function.
This same reasoning applies to your example, but I've removed the variant, and custom overload set, as it simplifies the situation, without changing the underlying problem.

Change Operation at runtime in C++

I have a small problem at hand. Suppose there is a if condition with only 2 operands but I want to make the operation dynamic.
void somFunc()
{
if(a && b) /*1*/
{
}
else if(a1 && b1) /*2*/
{
}
else if(a || b) /*3*/
{
}
else if(a1 || b1) /*4*/
}
Basically, 1 and 3 exactly has same parameters with different operation,Similarly for 2 and 4. I want to reduce these 4 operations to 2.
I want to know if there is a way I can make oper dynamic. Consider we only have 2 operations && and ||Can I use templates in any way ?
If someone wants to know why I need this is, there are n if conditions inside a big if/else. If I somehow achieve this, I reduce the conditions by half.
Not sure if this is what you are asking for, but you can write something like this:
enum OPERATION { AND, OR };
bool operation(bool a, bool b,OPERATION op) {
if (op == AND) return a && b;
return a || b;
}
void somFunc(OPERATION op)
{
if(operation(a,b,op))
{
}
}
Or as suggested in a comment, make the operation to be performed a parameter of the function, like so
template <OPERATION>
void somFunc(OPERATION op)
{
if(op(a,b))
{
}
}
and call it like this
somFunc( [](bool a, bool b) { return a && b; });
somFunc( [](bool a, bool b) { return a || b; });
You can use pointers to funtions.
#include <iostream>
#include <functional>
bool oper1(bool a, bool b) {
return a || b;
}
bool oper2(bool a, bool b) {
return a && b;
}
int main() {
bool a = true, b = false;
auto oper = oper1;
if (oper(a, b)) {
std::cout << "OR\n";
}
oper = oper2;
if (oper(a, b)) {
std::cout << "AND\n";
}
}
First you define all your conditions and later you can switch the condition by setting the variable.
You can also use inheritance and functors:
#include <iostream>
#include <functional>
#include <memory>
class Operator {
public:
virtual bool eval(bool a, bool b) = 0;
};
class OrOperator : public Operator {
public:
bool eval(bool a, bool b) {
return a || b;
}
};
class AndOperator : public Operator {
public:
bool eval(bool a, bool b) {
return a && b;
}
};
class VariableOperator : public Operator {
public:
VariableOperator(bool val) : val(val) {}
bool eval(bool a, bool b) {
return val;
}
private:
bool val;
};
int main() {
bool a = true, b = false;
std::unique_ptr<Operator> oper(new OrOperator);
if (oper->eval(a, b)) {
std::cout << "OR\n";
}
oper.reset(new AndOperator);
if (oper->eval(a, b)) {
std::cout << "AND\n";
}
oper.reset(new VariableOperator(true));
if (oper->eval(a, b)) {
std::cout << "VARIABLE\n";
}
}
You might be looking for something like this:
void somFunc()
{
std::vector< std::function< bool(bool, bool) > > operators = {
[](bool a, bool b){ return a && b; },
[](bool a, bool b){ return a || b; }
};
for ( auto& op : operators )
{
if ( op( a, b ) )
{
}
else if ( op( a1, b1 ) )
{
}
}
}
You can add more operators or change the parameter types easily enough.
You can do this with CRTP too:
#include <iostream>
#include <string>
#include <memory>
template<class T>
class Operation
{
public:
bool eval(bool a, bool b)
{
return this->impl().eval(a,b);
}
private:
T& impl() { return static_cast<T&>(*this); }
};
class AndOperation : public Operation<AndOperation>
{
public:
bool eval(bool a, bool b)
{
return a && b;
}
};
class OrOperation : public Operation<OrOperation>
{
public:
bool eval(bool a, bool b)
{
return a || b;
}
};
int main()
{
AndOperation andOp;
auto anonOp = std::make_unique<OrOperation>();
std::cout << andOp.eval(true, true) << std::endl;
std::cout << anonOp->eval(false,false);
}
see live example here
What are the advantages of CRTP over virtual inheritance?
CRTP is a case of static polymorphism. Here's some references:
Compile time vs run time polymorphism in C++ advantages/disadvantages
What is the motivation behind static polymorphism in C++?
C++: How is this technique of compile-time polymorphism called and what are the pros and cons?
The cost of dynamic (virtual calls) vs. static (CRTP) dispatch in C++
It is possible to make somFunc() a template, and accept any function that accepts two arguments and returns a value that can be tested with if.
#include <functional> // for binary operations in std
template<class Operation> void somfunc(Operation oper)
{
if (oper(a,b))
{
// whatever
}
}
int main()
{
somFunc(std::logical_and<int>());
somFunc(std::logical_or<int>());
somFunc(std::plus<int>()); // addition
// pass a lambda
somFunc([](int a, int b) -> int {return a + b;}); // lambda form of addition
}
In the above, I've assumed the variables a and b (which have been used in the question, but types unspecified) are of type int.

lambdas and equality/inequality operator

I have a question about equality comparison of lambdas.
I've tried to read some references but I've found nothing about this.
[] (Args ...args) -> ReturnType { ... };
For this type of lambdas, which are not closures actually because they have empty capture list, operators == and != works in the same way as for static functions (well, it seems, compiler generates them as static functions as well). But for closures any attempt to compare in the same way causes compilation error.
Here is simple programm for example:
#include <typeinfo>
#include <iostream>
struct WrapperBase {
virtual ~WrapperBase() = default;
virtual bool operator==(WrapperBase& v) = 0;
virtual bool operator!=(WrapperBase& v) = 0;
};
template<typename _Tp>
struct Wrapper : WrapperBase {
Wrapper(const _Tp& v) : value(v) { }
bool operator==(WrapperBase& v) override {
try {
Wrapper<_Tp>& vv = dynamic_cast<Wrapper<_Tp>&>(v);
return value == vv.value;
}
catch(std::bad_cast& err) { }
return false;
}
bool operator!=(WrapperBase& v) override {
try {
Wrapper<_Tp>& vv = dynamic_cast<Wrapper<_Tp>&>(v);
return value != vv.value;
}
catch(std::bad_cast& err) { }
return true;
}
//
_Tp value;
};
template<typename _Tp>
WrapperBase* create_wrapper(const _Tp& v) {
return new Wrapper<_Tp>(v);
}
struct Base {
Base(int a, int b) : wrapper(nullptr), a(a), b(b) { }
virtual ~Base() { delete wrapper; }
virtual WrapperBase* create_wrapper() = 0;
WrapperBase* wrapper;
int a;
int b;
};
struct ClassA : Base {
ClassA(int a, int b) : Base(a, b) {
wrapper = create_wrapper();
}
WrapperBase* create_wrapper() override {
auto lambda = [] (int v1, int v2) { return v1 + v2; };
return ::create_wrapper(lambda);
}
};
struct ClassB : Base {
ClassB(int a, int b) : Base(a, b) {
wrapper = create_wrapper();
}
WrapperBase* create_wrapper() override {
auto lambda = [=] (int v1, int v2) { return a + b + v1 + v2; };
return ::create_wrapper(lambda);
}
};
int main(int argc, char** argv) {
std::cout << std::boolalpha;
// all works fine:
ClassA a1(1, 2);
ClassA a2(3, 4);
std::cout << (*a1.wrapper == *a1.wrapper) << std::endl; // true
std::cout << (*a2.wrapper == *a2.wrapper) << std::endl; // true
std::cout << (*a1.wrapper == *a2.wrapper) << std::endl; // true
// cause compilation error:
ClassB b1(1, 2);
ClassB b2(3, 4);
std::cout << (*b1.wrapper == *b1.wrapper) << std::endl;
std::cout << (*b2.wrapper == *b2.wrapper) << std::endl;
std::cout << (*b1.wrapper == *b2.wrapper) << std::endl;
return 0;
}
Comparing lambdas created in instances of ClassA always return true even if they are created in different context (just as I said). On the other hand, ClassB do not even compile because operator == and != for its lambda is not found.
It seems, this programm is not well-formed, and comparing of lambdas in the way I've tried causes undefined behavior of the programm. But if it's really undefined behavior, how can they be compared? (I guess, nohow)
For this type of lambdas, which are not closures actually because they
have empty capture list, operators == and != works in the same way as
for static functions (well, it seems, compiler generates them as
static functions as well).
It works because the closure type of a lambda without captures provides a conversion operator that returns a function pointer. Those are comparable. [expr.prim.lambda]/6 (emphasis mine):
The closure type for a lambda-expression with no lambda-capture
has a public non-virtual non-explicit const conversion function to
pointer to function having the same parameter and return types as the
closure type’s function call operator. The value returned by this
conversion function shall be the address of a function that, when
invoked, has the same effect as invoking the closure type’s function
call operator.
(If the conversion operator was explicit the comparison would not work)
Roughly, a lambda of the form [] {} translates to
struct closure_type
{
private:
static void call() {}
public:
// closure_type() = delete; // Commented for the sake of the demo
closure_type& operator=(closure_type const&) = delete;
void operator()() const { /*return call();*/ }
operator decltype(&call)() const
{
return &call;
}
};
As you may have noted, the conversion operator returns the same function pointer each time. Though it would be utterly surprising if anything the like happened, the standard does allow different function pointers to be returned for a call to the conversion operator for the same closure object; A comparison of two closure objects has therefore an implementation-defined value. (It should, though, on all implementations be true for two closure objects of the same type.)

combining 3 functors into 1

I have 3 functors and was wondering if these can be combined into 1, perhaps as a template.
is it possible? if so, how would I do it. thx!
struct less_than
{
bool operator()(double prev,double curr) const
{
return prev<curr;
}
};
struct great_than
{
bool operator()(double prev,double curr) const
{
return prev>curr;
}
};
struct equal_to
{
bool operator()(double prev, double curr) const
{
return prev==curr;
}
};
If you mean, specialized by the operator, then the answer is, no, not at the language level.
Luckily, the STL already provides functors for this (std::equal_to, etc.). You can either use these directly, or use them as arguments to your own function classes.
As these are all existent in the standard library, you can just do
template<class F>
struct compare
{
compare(F _f)
: f(_f) {};
bool operator()(double prev, double curr) const
{
return f(prev, curr);
}
F f;
};
And use e.g. compare< std::less<double> >. But this would be quite useless, as you can just use the standard library functors directly.
You can do something like this:
class Functors
{
private:
bool f1(double, double)
{
}
bool f2(double, double)
{
}
bool f3(double, double)
{
}
public:
bool test(int op, double a, double b)
{
//better use function selector, this is only simple example
if (op == 1)
return f1(a, b);
if (op == 2)
return f2(a, b);
if (op == 3)
return f3(a, b);
}
};
use it:
vector<double> v;
int op = select_op();
//sort vector
std::sort(v.begin(), v.end(), boost::bind(&Functors::test, Functors(), op, _1, _2));