Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

static_cast<T&&>(t) faster than std::forward<T>(t) for compilation?

Recently, I've read a commit comment from range-v3 here: https://github.com/ericniebler/range-v3/commit/a4829172c0d6c43687ba213c54f430202efd7497

The commit message says,

marginally improve compile times by replacing std::forward with static_cast

I know that std::forward<T>(t) returns static_cast<T&&>(t), by standard. Also I do know sometimes static_cast<T&&>(t) will work fine when T &&t is universial referece(or forwarding reference) by reference collapsing rule.

What I'm interested in is the commit message says that static_cast improves marginally compile performance. If std::forward<T>(t) just returns static_cast<T&&>(t), what makes such differerence in compile performance?

Maybe does std::forward<T>(t) require some kind of deduction anyway? Or, Does std::forward<T>(t) do some magical thing which throttles compiler?

like image 588
xylosper Avatar asked Apr 11 '17 15:04

xylosper


People also ask

What is static_cast used for?

The static_cast is used for the normal/ordinary type conversion. This is also the cast responsible for implicit type coercion and can also be called explicitly. You should use it in cases like converting float to int, char to int, etc. This can cast related type classes.

What happens when static_cast fails?

As we learnt in the generic types example, static_cast<> will fail if you try to cast an object to another unrelated class, while reinterpret_cast<> will always succeed by "cheating" the compiler to believe that the object is really that unrelated class.

What happens when you perform a static_cast?

C-style casts also ignore access control when performing a static_cast , which means that they have the ability to perform an operation that no other cast can.

What is the difference between Dynamic_cast and static_cast?

Static casting is done by the compiler: it treats the result as the target type, no matter what. You do this when you're absolutely sure about the argument being of the target type. Dynamic casting is done at runtime, and thus requires runtime type information.


1 Answers

Every time you do std::forward<T>(t), the compiler has to instantiate several templates: std::forward itself has two overloads, as well as remove_reference which is part of the function's signature. And while these templates don't generate much code, it still has to do the work of template instantiation.

For most code, this would be essentially a rounding error in compile time. But for Ranges TS, with all of the forwarding of stuff they do there, it could be non-trivial (though still "marginal").

like image 140
Nicol Bolas Avatar answered Sep 20 '22 21:09

Nicol Bolas