Reference:
https://www.reddit.com/r/cpp/comments/6mzxsf/c_unnamed_programming/
http://nosubstance.me/post/cpp-unnamed-programming/
https://cplusplus.github.io/EWG/ewg-active.html#35
https://github.com/jeaye/value-category-cheatsheet/blob/master/value-category-cheatsheet.pdf
http://en.cppreference.com/w/cpp/language/reference_initialization#Lifetime_of_a_temporary
https://stackoverflow.com/questions/39279074/what-does-the-void-in-decltypevoid-mean-exactly
Unnamed variable.
Used for, i.e,
std::lock_guard
constructor that takes only l-value but no r-value. (i.e, an unnamed pr-value object can't be used)
First attempt:
Evaluation order is NOT guaranteed.
Thus, second attempt:
Using , operator
Using void type constructor to avoid user defined type , operator overload.
i.e, void() type instance is a void object.
what-does-the-void-in-decltypevoid-mean-exactly
Make a pr-value object a l-value:
Be aware that the pr-value will dangle after complete the function call expression.
Initializing the parameter of type int&& a temporary object of value 42 is created ([dcl.init.ref]/(5.2.2.2)),
the temporary object persists until the completion of the full-expression containing the call ([class.temporary]/(5.2)).
usage:
https://www.reddit.com/r/cpp/comments/6mzxsf/c_unnamed_programming/
http://nosubstance.me/post/cpp-unnamed-programming/
https://cplusplus.github.io/EWG/ewg-active.html#35
https://github.com/jeaye/value-category-cheatsheet/blob/master/value-category-cheatsheet.pdf
http://en.cppreference.com/w/cpp/language/reference_initialization#Lifetime_of_a_temporary
https://stackoverflow.com/questions/39279074/what-does-the-void-in-decltypevoid-mean-exactly
Unnamed variable.
Used for, i.e,
std::lock_guard
constructor that takes only l-value but no r-value. (i.e, an unnamed pr-value object can't be used)
First attempt:
Evaluation order is NOT guaranteed.
#include <mutex>
namespace detail {
template<typename First>
decltype(auto) select_last(First& first) {
return first;
}
// Returns a lvalue reference to the last element.
template<typename First, typename... Rest>
decltype(auto) select_last(First&, Rest&... rest) {
return select_last(rest...);
}
}
// Takes a number of arguments and invokes the last one as a function.
// Ignores all other arguments.
template<typename... T>
void with(T&&... objects) {
auto& fn = detail::select_last(objects...);
fn();
}
int g_i = 0;
std::mutex g_mutex;
int main() {
with(std::lock_guard<std::mutex>(g_mutex),
[&]() {
++g_i;
}
);
}
Thus, second attempt:
Using , operator
void safe_increment() {
std::lock_guard<std::mutex>{g_i_mutex}, ++g_i;
}
Using void type constructor to avoid user defined type , operator overload.
i.e, void() type instance is a void object.
what-does-the-void-in-decltypevoid-mean-exactly
void(UDT("1")), void(UDT("2")), [] {
cout << "hello" << endl;
}();
Make a pr-value object a l-value:
Be aware that the pr-value will dangle after complete the function call expression.
Initializing the parameter of type int&& a temporary object of value 42 is created ([dcl.init.ref]/(5.2.2.2)),
the temporary object persists until the completion of the full-expression containing the call ([class.temporary]/(5.2)).
template <typename T>
constexpr T& lvalue(T &&r) noexcept { return r; } // return l-value
usage:
vector<char> data(
istreambuf_iterator<char>(lvalue(ifstream("file.dat", ios::binary))),
{});
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.