Using in as a parameter qualifier

Ali Çehreli acehreli at yahoo.com
Fri May 31 11:20:14 PDT 2013


On 05/31/2013 10:49 AM, Shriramana Sharma wrote:

 >> struct Pair {
 >>      double x = 10.75;
 >>      double y = 20.25;
 >>
 >>      // Default constructor disabled
 >>      @disable this();
 >>
 >>      // Users must use another constructor:
 >>      this(double x, double y) { this.x = x; this.y = y; }
 >> }
 >>
 >> As you see, you must also provide a proper constructor that is 
appropriate
 >> for that type.
 >
 > Sorry but I still don't get it -- if a default constructor is
 > disallowed for struct-s by the language itself, why should I have to
 > *tell* the compiler to disable it?

Not when you "have to", when you "want to" disable it.

 >> However, :) if you are going to make a copy of the argument anyway, 
always
 >> take a struct by-value. That works with both lvalue and rvalue 
arguments and
 >> in the case of rvalues, you will get the automatic move semantics.
 >>
 >> My choice is by-value for structs unless there is any reason not to.
 >
 > So where is the cut-off point? I mean, by-value means a copy is done
 > every time the function is called right? So how heavy (in terms of
 > sizeof) would a struct have to be to make passing by ref more
 > efficient than passing by value?

Nobody knows. The cut-off point would move at any direction by the next 
generation of CPUs and systems.

 >> be slower than taking by-value. This is the idiomatic way of writing
 >> operator= in C++:
 >>
 >>      Foo & operator= (Foo that)
 >>      {
 >>          this->swap(that);
 >>          return *this;
 >>      }
 >
 > This assumes that Foo defines a swap method.

This is not a C++ forum, but... :) Yes, it must define a non-throwing 
swap member function. That function is almost always extremely fast.

 > Maybe good for lists and
 > such. ... One sec... if you take an argument by value, it means the
 > copy constructor would be called.

We are talking about assignment, which happens to be copy+destroy. No 
problem there.

 > So how is this really more efficient
 > than taking const Foo & as an argument?

It as efficient as an exception-safe operator=. It is not as efficient 
as incorrectly written operator=.

 >>> it makes optimization sense to not copy it but just automatically 
provide
 >>> a
 >>> reference to it right?
 >>
 >> Unless the language makes a guarantee about that we cannot take the 
address
 >> of the parameter and save it. We wouldn't know whether it is a copy or a
 >> reference.
 >
 > Can you explain? It's not very clear to me.

I thought your proposal was "compiler should automatically provide a 
reference when it makes sense to."

I meant: Assume that you wrote such a function where the compiler can 
play such a trick. You would not be sure whether you can take the 
address of the parameter and store it for later use, even inside the 
function, even to print a diagnostic message. The reason is, you 
wouldn't know whether the parameter was a reference to the argument or a 
copy of it.

 >> Another reason is less surprise because structs have copy semantics by
 >> default.
 >
 > Makes me start thinking I should use class rather than struct for my
 > pair even though there is no polymorphism etc required. Then I can
 > just say abs2(const pair). It would automatically be a reference.
 > Would that be inadvisable for any reason? My program would use pairs
 > heavily. Would the heap allocation/deallocation/GC be a burden if I
 > made the pair a class?

Sounds like you really have to run some test code to figure out what 
will work best for you. But in theory, no, your pair is not a class. It 
is a simple value type.

If you will have member functions, classes will be slower unless you 
mark those member function as 'final'. Also, class variables always 
bring an indirection because they are reference types.

Ali



More information about the Digitalmars-d-learn mailing list