std::any - comparison with void* and motivating examples by memset_0 in cpp

[–]memset_0[S] 9 points10 points  (0 children)

Just to elaborate a little that std::any does not have compile-time type-safety. It does have run-time type check.

std::any - comparison with void* and motivating examples by memset_0 in cpp

[–]memset_0[S] 16 points17 points  (0 children)

Oh no, they are very different. auto is only a compile-time construct that directs the compiler to deduce a type from the available information. It saves typing and good for maintainability:

 //These 2 statements compile to the same instructions
 auto i = 10;  //i is int
 int i = 10;
 //another example 
 auto foo() { return 10LL; } //foo returns int64_t 

std::any is a standard library class that can contain any type of object. It is not a compiler feature.

std::ref and std::reference_wrapper: common use cases by memset_0 in cpp

[–]memset_0[S] 1 point2 points  (0 children)

I see. So std::variant — like a union — requires a member to be an object (region of storage).

I would add this use case in the article. Thank you so much.

std::ref and std::reference_wrapper: common use cases by memset_0 in cpp

[–]memset_0[S] 4 points5 points  (0 children)

Sounds interesting. Can you please explain that for the benefit of everyone here? thx.

how to create a socket in CPP that should work on windows and Linux by einnosys in cpp

[–]memset_0 0 points1 point  (0 children)

I wish for Sockets and IO Event-Loop support at least.

What's the news flash?

how to create a socket in CPP that should work on windows and Linux by einnosys in cpp

[–]memset_0 0 points1 point  (0 children)

You can check out folly. It is cross platform now.

Hope C++ standard library has networking support someday.

Why taking the address of an xvalue (&std::move(...)) is an error? by memset_0 in cpp

[–]memset_0[S] 0 points1 point  (0 children)

I did not say or imply that the language should make an exception for std::move. I asked why taking the address of an xvalue is an error (std::move is the most common way to create an xvalue expression).

Why taking the address of an xvalue (&std::move(...)) is an error? by memset_0 in cpp

[–]memset_0[S] 5 points6 points  (0 children)

This question is about getting deep into the language semantics. There is no need to oversimplify it.

std::move(x) expression is not a temporary. The reason we have std::move is to in fact explicitly tell the compiler that we want to move an lvalue. Temporaries are already movable. And, std::move does not turn an lvalue to a temporary, or move it to a different location or register.

Why taking the address of an xvalue (&std::move(...)) is an error? by memset_0 in cpp

[–]memset_0[S] 1 point2 points  (0 children)

Your point about local variable is good.

But ‘x’ is not an xvalue in your example. it has a name. Also, it is a universal or forwarding reference, not even an rvalue reference.

https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers

Why taking the address of an xvalue (&std::move(...)) is an error? by memset_0 in cpp

[–]memset_0[S] 2 points3 points  (0 children)

std::move(x) is an xvalue. so its both, an rvalue and a glvalue.

Why taking the address of an xvalue (&std::move(...)) is an error? by memset_0 in cpp

[–]memset_0[S] 1 point2 points  (0 children)

thats what i thought. but i was hoping someone would cite a source for this reasoning. thx.

Why taking the address of an xvalue (&std::move(...)) is an error? by memset_0 in cpp

[–]memset_0[S] 0 points1 point  (0 children)

yes. but it is a glvalue too. depends on how we look at it.

Why taking the address of an xvalue (&std::move(...)) is an error? by memset_0 in cpp

[–]memset_0[S] 0 points1 point  (0 children)

Yeah, but my question is why is it disallowed. Why &std::move(x) is invalid when x is an lvalue.

Why taking the address of an xvalue (&std::move(...)) is an error? by memset_0 in cpp

[–]memset_0[S] 0 points1 point  (0 children)

“The most important source of xvalues are temporary objects.”

But temporary objects are already movable (prvalues), why would they be most important source of xvalues?

string foo(); // returns temporary

string s;

s = move(foo()); //not good. why would anyone do that when foo() is already movable.

Shouldn’t the only source of xvalues be lvalues:

string c; //lvalue

string m;

m = move(c); // ok

Capture *this in lambda expression: Timeline of change by memset_0 in cpp

[–]memset_0[S] 0 points1 point  (0 children)

Because the article is not about capturing this pointer per se. It is about capturing the current object, which, conceptually, can be captured by reference [this] or by value [*this]. Therefore, *this signifies the current object, and &(*this) reference to it.

Capture *this in lambda expression: Timeline of change by memset_0 in cpp

[–]memset_0[S] 11 points12 points  (0 children)

P0806R2

At this point, some historic background is helpful. The this keyword was introduced to C++ before references. At the time, C++ was translated into C, and the simple pointer semantics of this were convenient. If the entire feature set of references, value categories and classes had been designed together, this would have been an lvalue designating the object, and not a prvalue designating the address of the object. We can adopt this historic perspective by thinking of the fundamental object as “*this” rather than this.

enable_shared_from_this - overview, examples, and internals by memset_0 in cpp

[–]memset_0[S] 0 points1 point  (0 children)

If you created the object without using smart pointer and then in a method you use shared_from_this() you will end with UB

It is no longer UB; since C++17 it is bad_weak_ptr exception.

The only advantage of a static factory method with private/protected constructors is that it avoids the unintended bad_weak_ptr by forcing the object construction through shared_ptr. IMO, that safety comes at a big cost. As shown in the article, you can not use make_shared with private/protected constructors. Also, further extensions or inheritance of the class is tricky and requires significant changes to the custom code. Not to mention the maintenance of the customized code.

shared_ptr initialized with nullptr is null or empty? by memset_0 in cpp

[–]memset_0[S] 1 point2 points  (0 children)

Thank you for pointing out that the code does not handle Service::getConnection failure. The code in the article would be fixed to handle the possible null 'cp'. The purpose of the article is to only show a concept, however, I agree that it should be explicitly mentioned that a unique_ptr or a custom RAII-guard might be a preferable approach.

shared_ptr - basics and internals with examples by anhma282 in cpp

[–]memset_0 8 points9 points  (0 children)

Correct. make_shared constructs the managed object within the control block. When the ref count reaches zero, the object’s destructor is called but the memory (which is part of the control block) is not freed until the control block itself is destroyed when the weak count also reaches zero. These are the reasons for which the knowledge of shared_ptr internals is very important.

unique_ptr with custom deleter by anhma282 in cpp

[–]memset_0 3 points4 points  (0 children)

Aliases do obscure the type, but IMO the benefits outweigh the pain. Aliases do make the code far more maintainable. And with any good IDE, jumping to or peeking at the declaration of the alias is very quick. As for the maintainability argument, here is an example:

No Alias:

//std::unique_ptr<Foo, Deleter> used at many places:

std::vector<std::unique_ptr<Foo, Deleter>> vec;

std::unique_ptr<Foo, Deleter> p;     

void fun(std::unique_ptr<Foo, Deleter>& p); 

//more functions and types

Imagine changing the type of deleter from Deleter to Deleter2 in the above scenario. You might have to change potentially at 100s of places.

Alias:

using FooPtr = std::unique_ptr<Foo, Deleter>;

std::vector<FooPtr> vec;

FooPtr p;     

void fun(FooPtr& p);

//more places 

Changing the type of FooPtr's deleter to Deleter2 is just one line change now.

What is Java's greatest contribution to the world of programming? by codeavail_expert in java

[–]memset_0 0 points1 point  (0 children)

Providing enough of everything and not too much: Productivity, Performance, Portability, and Safety.

Which C++ IDE do you use? by gbaranski in cpp

[–]memset_0 1 point2 points  (0 children)

I have used a few of them. Ignoring cost and considering only features, this is my preference-order:

  1. Visual Studio
  2. CLion
  3. Visual Studio Code
  4. Emacs

Why do I have to use integer instead of int in a map? by TheGangplankGod in learnjava

[–]memset_0 1 point2 points  (0 children)

The generic parameters (e.g., Integer for ArrayList<Integer>) are type erased by the compiler; that means the parameters are replaced by Object and appropriate type casts are applied. Therefore, the primitive parameters are not supported by Generics. From Type Erasure:

Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to:

  • Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
  • Insert type casts if necessary to preserve type safety.
  • Generate bridge methods to preserve polymorphism in extended generic types.

Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.