What does static_cast mean when it's followed by two pairs of parentheses? - c++

What does this say:
return static_cast<Hasher &>(*this)(key);
?
I can't tell whether *this or key is passed to static_cast. I looked around and found this answer, but unlike what I'm stuck on, there's nothing inside the first pair of parentheses.

The statement is parsed as
return (static_cast<Hasher &>(*this))(key);
So, the argument to static_cast is *this. Then the result of the cast, let's call it x, is used as postfix-expression in a function call with key as argument, i.e. x(key), the result of which is returned.

I can't tell whether *this or key is passed to static_cast
If you're unsure, you can just look up the syntax.
In the informal documentation, the only available syntax for static_cast is:
static_cast < new-type > ( expression )
and the same is true in any standard draft you compare.
So there is no static_cast<T>(X)(Y) syntax, and the only possible interpretation is:
new-type = Hasher&
expression = *this
and the overall statement is equivalent to
Hasher& __tmp = static_cast<Hasher &>(*this);
return __tmp(key);
In the skarupke/flat_hash_map code you linked, the interpretation is that this class has a function call operator inherited from the private base class Hasher, and it wants to call that explicitly - ie, Hasher::operator() rather than any other inherited operator(). You'll note the same mechanism is used to explicitly call the other privately-inherited function call operators.
It would be more legible if it used a different function name for each of these policy type parameters, but then you couldn't use std::equal_to directly for the Equal parameter, for example.
It might also be more legible if it used data members rather than private inheritance for Hasher, Equal etc. but this way is chosen to allow the empty base-class optimization for stateless policies.

Related

C++ coalesce analogue

In c# i can use the syntax var c = a ?? b
receiving the first variable other than null (for nullable variables of same type). This is similar to the coallesce operator in transact-sql
DECLARE #c VARCHAR = COALESCE (#a, #b). Is there a way to write like this in C++?
There isn't a built-in operator like that in C++. Moreover, in C++, there isn't some highly-common null value which you set variables to: Integers, floating-points and Boolean variables cannot be null.
We do have a special "vocabulary type" named std::optional, where an std::optional<T> can hold either a value of type T or an "empty" / "nullopt" value - which is similar to what other languages use null for.
If a and b are optionals (of the same type), you could write:
auto c = a.value_or(b);
Note: The above works common, non-lvalue-reference types. Also, it will get rid of the optional<T> wrapper, i.e. you won't be able to assign nullopt to the result.
As einpoklum stated, there's no generalized concept of null variable in C++, but the types that do support a nullable state tend to expose a common interface: they explicitly convert to bool, and in that conversion they result being false if null, true otherwise.
This happens with pointers, for instance, or types that expose a pointer-like interface, like std::optional<T>.
In all those circumstances, you can use the ternary operator to achieve the result you want:
auto c = a ? a : b;
Contrary to a coalesce operator, though, the ternary operator may evaluate its first operand twice. This is not an issue with pointers (smart or raw) or std::optional<T> and other types that explicitly and const-ly convert to bool, but might be an issue with other types that have side effects during the conversion (can't imagine one, at the moment, and I'd dare say that any non-const conversion to bool should be deemed faulty).
Gcc, however, supports an extension, which lets you Not Repeat Yourself and avoid side effects. A true coalescing (elvis) operator:
auto c = a ?: b;
Which, incidentally, does seem to be quite the syntax you were looking for.

Global Operator "->" overload C++

I want to overload "->" operator globally for pointers. Is it possible?
A *var1 = new A(21);
int x = var1->someInt;
In that code it has to be triggered when reaching "var1"s "someInt" variable.
Actually I am trying to check the pointer before reaching its members. Also, I am trying to implement this system on a written code, so I don't want to change too much thing in the actual code.
I want to overload "->" operator globally. Is it possible?
No it is impossible.
Perhaps you might define a "root" class in your library or program (which would define that operator ->), and have all your classes inherit from it.
BTW, I am not sure you will be able to define your isPointerValid function in all cases (including the address of valid automatic variables of any class type), and efficiently.
There are many cases where you could not define such a function (e.g. union-s used in tagged union types; you don't easily know what member of a union is currently active. arbitrary casts; ...); .
For existing code and classes, the builtin meaning of -> (which you usually cannot redefine) has already been used to compile the code using them.
As described in C++17 standard draft in section 16.5.6 (emphasis mine):
An operator function shall either be a non-static member function or
be a non-member function that has at least one parameter whose type
is a class, a reference to a class, an enumeration, or a reference to
an enumeration.
Hence, it is not possible to overload an operator which doesn't take any arguments.

In C++ how do we call everything with a valid X(Args...) syntax that execute a function?

In C++, there is a Callable concept as well as the std::is_function type traits. I was wondering how the standard calls X, when the exact expression
X(Args...)
is valid and corresponds to a call (excluding constructors and C macros). For now, I can think of the following that fit in that category:
functions: R(Args...) (with optional const, volatile, &, && qualifiers)
function pointers: R(*)(Args...)
function references: R(&)(Args...)
functors (struct/class with overloaded operator())
lambda
My questions:
How does the standard call X? (eg.: not a is_function type because if X is a function pointer, X(Args...) is valid but is_function is false)
Did I forgot something in my list?
Your question seems a bit confused. std::is_function only identifies actual function types. It doesn't even include pointers to functions. The FunctionObject concept includes any object type that you can apply the function call operator to. This basically covers your list.
The Callable concept includes FunctionObjects, but it includes other things. Callable adds member pointers (both data and functions) to the rest of the FunctionObject family.
The INVOKE feature of C++ is what gets applied to all Callable objects. INVOKE is not actually a function in C++; it's simply the standard's name for the algorithm for calling Callable objects with an argument list (C++17 corrects this absurd overseight, giving us std::invoke). Section 20.9.2 of the standard covers exactly how this algorithm is implemented.
The general gist is what you would expect. If the callable is a pointer-to-member-data, then you take the first argument, and apply that to the pointer-to-member-data (dereferencing that argument if it isn't a pointer). Same goes for pointer-to-member-functions, only you pass the rest of the arguments as parameters.
For FunctionObject types, you just use () to call it, passing it the arguments.

overload "->" (member access) recursively

I am learning how to overload "->" and the documentation says that:
"operator-> is called again on the value that it returns, recursively, until the operator-> is reached that returns a plain pointer. After that, builtin semantics are applied to that pointer."
While it is clear what the documentation says, essentially that an overloaded "->" of a class could use itself a "special pointer" having itself an overloaded "->" that could give a "special pointer" etc etc until a "plain pointer" is found, I cannot find an example of a real use of it ( unless it is used to find a linked list last element ).
Could somebody explain what is the retionale behind the scenes, ( as that possibility isn't provided with "plain pointers" - so I dont' see any reason to provide it with "special pointers" ).
An example of real world use could help too, as probably I am missing a model where to apply the behaviour.
On the opposite side there could be the need to avoid that behaviour, how could it be done ?
Well, the -> operator works under rater special circumstances.
One can call it a pseudo-binary operator. According to its natural syntax pointer->member it takes two operands: a normal run-time operand on the left-hand side and a rather "strange" member name operand on the right-hand side. The "strangeness" of the second operand is rooted in the fact that C++ language has no user-accessible concept for representing such operands. There's nothing in the language that would express a member name as an operand. There's no way to "pass" a member name through the code to the user-defined implementation. The member name is a compile-time entity, remotely similar to constant expressions in that regard, but no constant expression in C++ can specify members. (There are expressions for pointers-to-members, but not for members themselves).
This creates rather obvious difficulties in specifying the behavior of overloaded -> operator: how do we connect what was specified on the right-hand side of -> (i.e the member name) to the code written by the user? It is not possible to do it directly. The only way out of this situation is to do it indirectly: force the user to channel the user-defined functionality of the overloaded -> operator into the functionality of some existing built-in operator. The built-in operator can handle member names naturally, through its core language capabilities.
In this particular case we have only two candidates to channel the functionality of the overloaded -> to: the built-in -> and the built-in .. It is only logical that the built-in -> was chosen for that role. This created an interesting side-effect: the possibility to write "chained" (recursive) sequences of overloaded -> operators (unwrapped implicitly by the compiler) and even infinitely recursive sequences (which are ill-formed).
Informally speaking, every time you use a smart pointer you make a real-world use of these "recursive" properties of overloaded -> operator. If you have a smart pointer sptr that points to a class object with member member, the member access syntax remains perfectly natural, e.g. sptr->member. You don't have to do it as sptr->->member or sptr->.member specifically because of the implicit "recursive" properties of overloaded ->.
Note that this recursive behavior is only applied when you use operator syntax for invoking the overloaded -> operator, i.e. the object->member syntax. However, you can also use the regular member function call syntax to call your overloaded ->, e.g. object.operator ->(). In this case the call is carried out as an ordinary function call and no recursive application of -> takes place. This is the only way to avoid the recursive behavior. If you implement overloaded -> operator whose return type does not support further applications of -> operator (for example, you can define an overloaded -> that returns int), then the object.operator ->() will be the only way to invoke your overloaded implementation. Any attempts to use the object->member syntax will be ill-formed.
I cannot find an example of a real use of it ( unless it is used to find a linked list last element ).
I think you're misunderstanding what it does. It isn't used to dereference a list element and keep dereferencing the next element. Each time you call operator-> you would get back a different type, the point is that if that second type also has an operator-> it will be called, which might return a different type again. Imagine it being like x->->->i not x->next->next->next if that helps
An example of real world use could help too, as probably I am missing a model where to apply the behaviour.
It can be useful for the Execute Around Pointer pattern.
On the opposite side there could be the need to avoid that behaviour, how could it be done ?
Call the operator explicitly:
auto x = p.operator->();

Why won't this c++ lamba function compile?

Why does this fail to compile:
int myVar = 0;
myVar ? []()->void{} : []()->void{};
with following error msg:
Error 2 error C2446: ':' : no conversion from 'red_black_core::`anonymous-namespace'::< lambda1>' to red_black_core::anonymous-namespace::< lambda0>
While this complies correctly:
void left()
{}
void right()
{}
int myVar = 0;
myVar ? left() : right();
The return type of the ?: operator has to be deduced from it's two operands, and the rules for determining this type are quite complex. Lambdas don't satisfy them because they can't be converted to each other. So when the compiler tries to work out what the result of that ?: is, then there can't be a result, because those two lambdas aren't convertible to each other.
However, when you try to compute the functions, then you actually called them, but you didn't call the lambdas. So when you call the functions, they both have void, so the return type of ?: is void.
This
void left()
{}
void right()
{}
int myVar = 0;
myVar ? left() : right();
is equivalent to
int myVar = 0;
myVar ? [](){}() : [](){}();
Note the extra () on the end- I actually called the lambda.
What you had originally is equivalent to
compiler_deduced_type var;
if (myVar)
var = [](){};
else
var = [](){};
But- no type exists that can be both lambdas. The compiler is well within it's rights to make both lambdas different types.
EDIT:
I remembered something. In the latest Standard draft, lambdas with no captures can be implicitly converted into function pointers of the same signature. That is, in the above code, compiler_deduced_type could be void(*)(). However, I know for a fact that MSVC does not include this behaviour because that was not defined at the time that they implemented lambdas. This is likely why GCC allows it and MSVC does not- GCC's lambda support is substantially newer than MSVC's.
Rules for conditional operator in the draft n3225 says at one point
Otherwise, the result is a prvalue. If the second and third operands do not have the same type, and either
has (possibly cv-qualified) class type, overload resolution is used to determine the conversions (if any) to be
applied to the operands (13.3.1.2, 13.6). If the overload resolution fails, the program is ill-formed. Otherwise,
the conversions thus determined are applied, and the converted operands are used in place of the original
operands for the remainder of this section.
Up to that point, every other alternative (like, convert one to the other operand) failed, so we will now do what that paragraph says. The conversions we will apply are determined by overload resolution by transforming a ? b : c into operator?(a, b, c) (an imaginary function call to a so-named function). If you look what the candidates for the imaginary operator? are, you find (among others)
For every type T , where T is a pointer, pointer-to-member, or scoped enumeration type, there exist candidate operator functions of the form
T operator?(bool, T , T );
And this includes a candidate for which T is the type void(*)(). This is important, because lambda expressions yield an object of a class that can be converted to such a type. The spec says
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.
The lambda expressions can't be convert to any other of the parameter types listed, which means overload resolution succeeds, finds a single operator? and will convert both lambda expressions to function pointers. The remainder of the conditional opreator section will then proceed as usual, now having two branches for the conditional operator having the same type.
That's why also your first version is OK, and why GCC is right accepting it. However I don't really understand why you show the second version at all - as others explained, it's doing something different and it's not surprising that it works while the other doesn't (on your compiler). Next time, best try not to include useless code into the question.
Because every lambda is a unique type. It is basically syntactic sugar for a functor, and two separately implemented functors aren't the same type, even if they contain identical code.
The standard does specify that lambdas can be converted to function pointers if they don't capture anything, but that rule was added after MSVC's lambda support was implemented.
With that rule, however, two lambdas can be converted to the same type, and so I believe your code would be valid with a compliant compiler.
Both snippets compile just fine with GCC 4.5.2.
Maybe your compiler has no (or partial/broken) support to C++0x features such as lambda?
It doesn't fail to compile. It works just fine. You probably don't have C++0x enabled in your compiler.
Edit:
An error message has now been added to the original question! It seems that you do have C++0x support, but that it is not complete in your compiler. This is not surprising.
The code is still valid C++0x, but I recommend only using C++0x features when you really have to, until it's standardised and there is full support across a range of toolchains. You have a viable C++03 alternative that you gave in your answer, and I suggest using it for the time being.
Possible alternative explanation:
Also note that you probably didn't write what you actually meant to write. []()->void{} is a lambda. []()->void{}() executes the lambda and evaluates to its result. Depending what you're doing with this result, your problem could be that the result of calling your lambda is void, and you can't do much with void.