Functor and function pointer logic - c++11

class StrangeFunctor
{
public:
StrangeFunctor(int (*comp)(string, string))
{
this->comp = comp;
}
int operator()(string str1, string str2)
{
return –comp(str1, str2);
}
private:
int (*comp)(string, string);
}
I was just curious as what the above code actually did. Assuming the functor was properly initialized and given to a sorting function for comparison purpose, my hunch is that it reverses the order of the passed argument, but I'm not sure if that is correct and why the would be correct.

This functor takes in a function pointer and then flips the sign on that method's return value.
return –comp(str1, str2);
If used with sorting like you said, it would invert the order of what was being sorted, given by the original function pointer.

Related

Reason of third return statement in method

I’m new to Go and to practice I do some coding exercice on Exercism. I stubbled on a particular exercice in which I’m having a hard time undestanding the solution. Here’s the code:
// Ints defines a collection of int values
type Ints []int
// Lists defines a collection of arrays of ints
type Lists [][]int
// Strings defines a collection of strings
type Strings []string
// Keep filters a collection of ints to only contain the members where the provided function returns true.
func (i Ints) Keep(strainer func(int) bool) (o Ints) {
for _, v := range i {
if strainer(v) {
o = append(o, v)
}
}
return
}
// Discard filters a collection to only contain the members where the provided function returns false.
func (i Ints) Discard(strainer func(int) bool) Ints {
return i.Keep(func(n int) bool { return !strainer(n) })
}
My Problem comes with the Discard Method, I dont understand the second return statement in the curly braces since the Keep function is suppose to return a value of type Ints and not a boolean statement unless I missed something, if someone could break down the Discard function for me it would be helpful.
Thanks
The Keep method takes a function as a parameter. It expects it to be func (int) bool - a function taking an int and returning a bool.
When Keep is invoked in Discard, the code passes it an anonymous function with the right signature (take int, return bool). This anonymous function invokes strainer (which is a function passed into Discard) and returns its response, negated.
The idea is that strainer is a filter function: it tells you which elements to keep. So the implementation of Keep is straightforward: iterate over all elements, and keep only those for which strainer returns true.
Discard is written in a clever way using Keep, instead of also writing a loop like this:
func (i Ints) Discard(strainer func(int) bool) (o Ints) {
for _, v := range i {
if !strainer(v) {
o = append(o, v)
}
}
return
}
It instead invokes Keep with a function that inverts the result of strainer.

unordered_set hash for type, whose comparison uses part of the type data

I need std::unordered_set of pairs, whose first elements should be different.
Is it correct to hash only first element of pairs, as below?
using Pair = std::pair<int, int>;
struct Eq
{
bool operator() ( Pair const& lhs,
Pair const& rhs ) const
{
return (lhs.first == rhs.first);
}
};
struct Hash
{
std::size_t operator() ( Pair const &p ) const
{
return std::hash<int>()( p.first );
}
};
// No two pairs with same '.first'.
std::unordered_set<Pair, Hash, Eq> pairs;
for ( Pair const& p : ... )
{
pairs.insert(p);
}
In general, for unordered_set<T>:
If equality functor for type T does not use part (some data members) of T, it makes sense not to use that part in hash<T> either.
Is this right?
Yeap, should work fine. From the documentation to std::unordered_set::insert() (emphasis mine):
Inserts element(s) into the container, if the container doesn't already contain an element with an equivalent key.
You clearly provided a predicate that says elements should be treated equivalent when their first fields match. And you specified a hash that makes sure equivalent elements end up in the same bucket. So this looks good to me.

Explicit and implicit conversion

I am pretty surprised that this struct, which is only explicitly convertible to bool, works fine inside a if statement:
struct A
{
explicit operator bool( ) const
{
return m_i % 2 == 0;
}
int m_i;
};
int main()
{
A a{ 10 };
if ( a ) // this is considered explicit
{
bool b = a; // this is considered implicit
// and therefore does not compile
}
return 0;
}
Why is it so? What is the design reason behind it in the C++ Standard?
I personally find more explicit the second conversion than the first one. To make it even more clear, I would have expected the compiler forcing to have the following for both the cases:
int main()
{
A a{ 10 };
if ( (bool)a )
{
bool b = (bool)a;
}
return 0;
}
§6.4 Selection statements [stmt.select]
The value of a condition that is an expression is the value of the expression, contextually converted to bool for statements other than switch;
§4 Standard conversions [conv]
Certain language constructs require that an expression be converted to
a Boolean value. An expression e appearing in such a context is said
to be contextually converted to bool and is well-formed if and only
if the declaration bool t(e); is well-formed, for some invented
temporary variable t (8.5).
So the expression of the condition in if must be contextually convertible to bool, which means that explicit conversions are allowed.
This is mode most likely done because the condition of if can only evaluate to a boolean value, so by saying if(cond) you are explicitly stating you want cond to be evaluated to a boolean value.

Is the unique_ptr returned from a function an lvalue?

Lately, I've been doing a little digging into the C++11 std and was playing around with unique_ptrs.
Let's say I have a function which returns a unique_ptr to an integer.
unique_ptr<int> GetUniquePtr(int i)
{
return make_unique<int>(i);
}
In my main function, I am able to take the address of the value returned by the function. This means that the expression must evaluate to an lvalue
int main()
{
cout << &(GetUniquePtr(5));
}
I know if I assign the function call to a unique pointer, the move consturctor of the unique_ptr will be called, treating the returned value as an rvalue reference.
int main()
{
unique_ptr<int> uPtr = GetUniquePtr(5);
}
This dual behaviour of returning unique_ptr kind of confuses me, as I was of the impression that unique_ptr returned from a function call is always evaluated as an rvalue.
Can anyone shed some light on what's actually going on?

C++11 Multiline lambdas can deduce intrinsic types?

I use C++11 lambdas quite a lot, and I've often run into compile errors on multiline lambdas because I forgot to add the return type, as is expected, but I recently ran into one example that doesn't have this issue. It looks something like this:
auto testLambda = [](bool arg1, bool arg2)
{
if (arg1)
{
if (!arg2)
{
return false;
}
return true;
}
return false;
};
This compiles just fine even though there's no return type specified. Is this just Visual Studio being dumb and allowing something it shouldn't, or can lambdas just always deduce intrinsic types?
I tried this with return values of all ints or floating point values and it also compiled just fine. I just found this to be really surprising so I wanted to be absolutely sure how it works before I start making assumptions and omitting return types that might break later on.
Lambdas follow the same template deduction rules as auto-returning functions:
Template argument deduction is used in declarations of functions, when deducing the meaning of the auto specifier in the function's return type, from the return statement.
For auto-returning functions, the parameter P is obtained as follows: in T, the declared return type of the function that includes auto, every occurrence of auto is replaced with an imaginary type template parameter U. The argument A is the expression of the return statement, and if the return statement has no operand, A is void(). After deduction of U from P and A following the rules described above, the deduced U is substituted into T to get the actual return type:
auto f() { return 42; } // P = auto, A = 42:
// deduced U = int, the return type of f is int
If such function has multiple return statements, the deduction is performed for each return statement. All the resulting types must be the same and become the actual return type.
If such function has no return statement, A is void() when deducing.
Note: the meaning of decltype(auto) placeholder in variable and function declarations does not use template argument deduction.

Resources