D struct copy constructor - constructor

Is it possible to call struct copy constructor explicitly, like in C++? Can I write something like this:
struct foo {
void bar() {}
}
foo f;
foo(f).bar();
Or I always need to assign new value to some varialbe?

Well, technically, D doesn't even have copy constructors. Rather, structs can have postblit constructors. e.g.
struct S
{
this(this)
{
}
}
In general, D tries to move structs as much as possible and not copy them. And when it does copy them, it does a bitwise copy of the struct and then runs the postblit constructor (if there is one) to mutate the struct after the fact to do stuff that needs to be done beyond a bitwise copy - e.g. if you want a deep copy of a member
struct S
{
this(this)
{
if(i !is null)
i = new int(*i);
}
int* i;
}
A copy constructor (in C++), on the other hand, constructs a new struct/class and initializes each member with a copy of the corresponding member in the struct/class being copied - or with whatever it's initialized with in the copy constructor's initializer list. It doesn't copy and then mutate like happens with D's postblit constructor. So, a copy constructor and a postblit constructor are subtly different.
One of the side effects of this is that while all structs/class in C++ have copy constructors (the compiler always generates one for you if you don't declare one), not all structs in D have postblit constructors. In fact, most don't. The compiler will generate one if the struct contains another struct that has a postblit constructor, but otherwise, it's not going to generate one, and copying is just going to do a bitwise copy. And, if there is no postblit construct, you can't call it implicitly or explicitly.
Now, if we compile this
struct A
{
}
pragma(msg, "A: " ~ __traits(allMembers, A).stringof);
it prints
A: tuple()
A has no members - be it member variables or functions. None have been declared, and the compiler has generated none.
struct B
{
A a;
string s;
}
pragma(msg, "B: " ~ __traits(allMembers, B).stringof);
prints
B: tuple("a", "s")
It has two members - the explicitly declared member variables. It doesn't have any functions either. Declaring member variables is not a reason for the compiler to generate any functions. However, when we compile
struct C
{
this(this)
{
import std.stdio;
writeln("C's postblit");
}
int i;
string s;
}
pragma(msg, "C: " ~ __traits(allMembers, C).stringof);
it prints
C: tuple("__postblit", "i", "s", "__xpostblit", "opAssign")
Not only are its two member variables listed, but it also has __postblit (which is the explicitly declared postblit constructor) as well as __xpostblit and opAssign. __xpostblit is the postblit constructor generated by the compiler (more on that in a second), and opAssign is the assignment operator which the compiler generated (which is needed, because C has a postblit constructor).
struct D
{
C[5] sa;
}
pragma(msg, "D: " ~ __traits(allMembers, D).stringof);
prints
D: tuple("sa", "__xpostblit", "opAssign")
Note that it has __xpostblit but not __postblit. That's because it does not have an explitly declared postblit constructor. __xpostblit was generated to call the postblit constructor of each of the member variables. sa is a static array of C's, and C has a postblit constructor. So, in order to copy sa properly, the postblit constructor for C must be called on each of the elements in sa. D's __xpostblit does that. C also has __xpostblit, but it doesn't have any members with postblit constructors, so its __xposblit just calls its __postblit.
struct E
{
this(this)
{
import std.stdio;
writeln("E's postblit");
}
C c;
}
pragma(msg, "E: " ~ __traits(allMembers, E).stringof);
prints
E: tuple("__postblit", "c", "__xpostblit", "opAssign")
So, E - like C - has both __postblit and __xpostblit. __postblit is the explicit postblit constructor, and __xpostblit is the one generated by the compiler, However, in this case, the struct actually has member variables with a postblit constructor, so __xpostblit has more to do than just call __postblit.
If you had
void main()
{
import std.stdio;
C c;
writeln("__posblit:");
c.__postblit();
writeln("__xposblit:");
c.__xpostblit();
}
it would print
__posblit:
C's postblit
__xposblit:
C's postblit
So, there's no real difference between the two, whereas if you had
void main()
{
import std.stdio;
D d;
writeln("__xposblit:");
d.__xpostblit();
}
it would print
__xposblit:
C's postblit
C's postblit
C's postblit
C's postblit
C's postblit
Notice that C' postblit gets called 5 times - once for each element in D's member, sa. And we couldn't call __postblit on D, because it doesn't have an explicit postblit constructor -
just the implicit one.
void main()
{
import std.stdio;
E e;
writeln("__posblit:");
e.__postblit();
writeln("__xposblit:");
e.__xpostblit();
}
would print
__posblit:
E's postblit
__xposblit:
C's postblit
E's postblit
And in this case, we can see that __postblit and __xpostblit are different. Calling __postblit just calls the explicitly declared postblit constructor, whereas __xpostblit calls it and the postblit constructors of the member variables.
And of course, since, A and B don't have posblit constructors and no members that have them, it would be illegal to call either __postblit or __xpostblit on them.
So, yes, you can call the postblit constructor explicitly - but only if it has one, and you almost certainly shouldn't be calling it. If a function starts with __, or it's one of the overloaded operators (and thus starts with op), then it almost never should be called explicitly - and that includes the postblit constructor. But if you do find a legitimate reason to call it, remember that you're probably going to want to call __xpostblit rather than __postblit, otherwise the postblit for the member variables won't be run. You can test for it by doing __traits(hasMember, S1, "__xpostblit") or by using the badly named hasElaborateCopyConstructor from std.traits (most code should use hasElaborateCopyConstructor, since it's more idiomatic). If you want to call __postblit for some reason, you'll need to test for it with __traits rather than std.traits though, because pretty much nothing outside of druntime cares whether a type declared __postblit. The stuff that does care about posblit constructors cares about __xpostblit, since that can exist whether __postblit was declared or not.

D doesn't have copy constructors per se, but you could call the implicit constructor with the contents of the existing one (which would create a shallow copy at least) with
foo(f.tupleof).bar()
The f.tupleof gives the list of struct members in a form that is suitable for automatic expansion to a function argument list.

Related

Why can't the "`main`" function be declared as a lambda in Kotlin?

The following trivial Kotlin code snippet
fun main() {}
compiles just fine, but the following
val main : () -> Unit = {}
makes the compiler complain that "No main method found in project.", while I was expecting them to be equivalent (I expect a programming language to be as conceptually uniform as possible).
Why does this happen? Is it related only to main, or does this behaviour concern a larger class of functions? Is there some subtle difference between declaring functions with "fun" and declaring them as lambdas?
Conceptually, they are different things. To see that, let's take a look at roughly what the equivalent Java would be. I'll use JVM for examples in this answer, but the same principles apply to all of the other Kotlin backends.
object Foo {
fun main() { ... }
}
This is roughly
class Foo {
public static void main() { ... }
}
Again, roughly. Technically, you'll get a singleton object and a method on it unless you use #JvmStatic (I assume there's some special handling for main that produces a static function on JVM, but I don't know that for a fact)
On the other hand,
object Foo {
val main: () -> Unit = { ... }
}
Here, we're declaring a property, which in Java is going to get implemented as a getter-setter pair
class Foo {
// Singleton instance
public static Foo instance = new Foo();
public Supplier<Void> main;
Foo() {
main = new Supplier<Void>() {
Void get() {
...
}
}
}
}
That is, there isn't actually a main method. There's a main field which, deep down somewhere, has a function inside of it. In my example above, that function is called get. In Kotlin, it's called invoke.
The way I like to think of it is this. Methods in Kotlin (i.e. the things you define on objects that designate their behavior) are not themselves first-class objects. They're second-class citizens which exist on an object. You can convert them to first-class objects by making them into functions. Functions are ordinary objects, like any other. If you take an ordinary object, which may or may not be a function, and call it with (), then you're actually invoking the method .invoke(...) on it. That is, () is an operator on objects which really ends up calling a method. So in Kotlin, functions are really just objects with a custom invoke and a lot of syntax sugar.
Your val defines a field which is a function. Your fun defines a method. Both of these can be called with (), but only one is a genuine method call; the other is secretly calling .invoke on another object. The fact that they look syntactically the same is irrelevant.
As the old adage goes, functions are a poor man's objects, and objects are a poor man's functions.
There is a subtle (or more than subtle) difference. Declaring it with val means that main is a property containing a reference to an anonymous function (which you defined with the lambda). If you define it with val, then when you call main(), you are actually calling the getter of the main property, and then using the invoke() operator to call invoke() on the return value of the property (the anonymous function).

C++11: Why result_of can accept functor type as lvalue_reference, but not function type as lvalue_reference?

I've got program below:
#include<type_traits>
#include<iostream>
using namespace std;
template <class F, class R = typename result_of<F()>::type>
R call(F& f) { return f(); }
struct S {
double operator()(){return 0.0;}
};
int f(){return 1;}
int main()
{
S obj;
call(obj);//ok
call(f);//error!
return 0;
}
It fails to compile in the line of "call(f)".
It's weird that "call(obj)" is OK.
(1) I've a similar post in another thread C++11 result_of deducing my function type failed. But it doesn't tell why functor objects are OK while functions are not.
(2) I'm not sure if this is related to "R call(F& f)": a function type cannot declare a l-value?
(3) As long as I know, any token with a name, like variable/function, should be considered a l-value. And in the case of function parameter, compiler should "decay" my function name "f" to a function pointer, right?
(4) This is like decaying an array and pass it to a function----And a function pointer could be an l-value, then what's wrong with "call(F& f)"?
Would you help to give some further explanations on "why" is my case, where did I get wrong?
Thanks.
The problem with call(f) is that you deduce F as a function type, so it doesn't decay to a function pointer. Instead you get a reference to a function. Then the result_of<F()> expression is invalid, because F() is int()() i.e. a function that returns a function, which is not a valid type in C++ (functions can return pointers to functions, or references to functions, but not functions).
It will work if you use result_of<F&()> which is more accurate anyway, because that's how you're calling the callable object. Inside call(F& f) you do f() and in that context f is an lvalue, so you should ask what the result of invoking an lvalue F with no arguments is, otherwise you could get the wrong answer. Consider:
struct S {
double operator()()& {return 0.0;}
void operator()()&& { }
};
Now result_of<F()>::type is void, which is not the answer you want.
If you use result_of<F&()> then you get the right answer, and it also works when F is a function type, so call(f) works too.
(3) As long as I know, any token with a name, like variable/function, should be considered a l-value. And in the case of function parameter, compiler should "decay" my function name "f" to a function pointer, right?
No, see above. Your call(F&) function takes its argument by reference, so there is no decay.
(4) This is like decaying an array and pass it to a function----And a function pointer could be an l-value, then what's wrong with "call(F& f)"?
Arrays don't decay when you pass them by reference either.
If you want the argument to decay then you should write call(F f) not call(F& f). But even if you do that you still need to use result_of correctly to get the result of f() where f is an lvalue.

Immutability in D constructors

My previous question discussed making a copy constructor like so:
struct Foo {
int i;
this(int j) { i = j; }
this(Foo rhs) { this = rhs; }
}
void main()
{
auto f = Foo(5);
auto g = new Foo(f);
}
But, if I make i immutable, the constructor fails to compile with
Error: cannot modify struct this Foo with immutable members
Why is this the case? I was under the impression that immutable members of a class or struct do not become immutable until the end of the constructor is reached.
Okay. In general, I'd advise against having structs with immutable members. There are just too many places where it's useful to be able to assign to one. What you typically want to do with a struct is make it so that it can be mutable, const, or immutable as a whole. And for the most part, that just works. e.g.
struct Foo
{
int i;
this(int j) { i = j; }
this(Foo rhs) { this = rhs; }
}
void main()
{
immutable f = Foo(5);
}
compiles just fine. The one area that generally causes trouble with that is when you have to have a postblit constructor, because those don't currently work with const or immutable structs (it's something that sorely needs to be fixed, but it's still an open problem due to how the type system works - it may result in us having to add copy constructors to the language, or we may figure out how to do it, but for now, it doesn't work, and it can be annoying). But that only affects you if you need a postblit constructor, which most structs don't need (the problem will be fixed eventually though, because it really needs to be; it's just a question of how and when).
However, to answer your question more generally, let's look at a class. For instance, this code won't compile, because the constructor is not immutable, and the compiler can't convert an immutable class object to a mutable one (it can do that with structs, because it makes a copy, but with a class, it's just copying the reference, not the object, so it doesn't work):
class Foo
{
int i;
this(int j) { i = j; }
}
void main()
{
auto f = new immutable Foo(5);
}
Instead of that compiling, you get this lovely error message:
q.d(10): Error: mutable method q.Foo.this is not callable using a immutable object
q.d(10): Error: no constructor for Foo
There are three ways to solve this. The first is to make the constructor immutable
class Foo
{
int i;
this(int j) immutable { i = j; }
}
and that works, but it makes it so that you can only construct Foos which are immutable, which usually isn't what you want (though it sometimes is). So, the second way to solve the problem would be to take the first solution a step further and overload the constructor. e.g.
class Foo
{
int i;
this(int j) { i = j; }
this(int j) immutable { i = j; }
}
However, that requires code duplication, which isn't a lot here, but it could be a lot for other types. So, what is generally the best solution is to make the constructor pure.
class Foo
{
int i;
this(int j) pure { i = j; }
}
This works, because the compiler then knows that nothing has escaped the constructor (since pure guarantees that nothing escapes by being assigned to a global or static variable, and the constructor's parameters don't allow anything to escape either), and because it knows that no references to Foo or its members can escape the constructor, it knows that there are no other references to this Foo and that it therefore can safely convert it to mutable, const, or immutable without violating the type system. Of course, that only works if you can make the constructor pure and nothing can escape via the constructor's arguments, but that's usually the case, and when it isn't, you can always just overload the constructor on mutability, much as that's less desirable.
The same techniques can be used on structs if you really want const or immutable members, but again, I'd advise against it. It's just going to cause you more trouble than it's worth, especially when it's usually trivial to just make the whole struct const or immutable when declaring a variable.
Making members of structs immutable stops assigning to the struct which in turn causes quite a few issues, you may which to rethink that.
Otherwise assign the members directly instead of relying on the assignment operator:
struct Foo {
immutable int i;
this(int j) { i = j; }
this(in Foo rhs) { this.i = rhs.i; }
}

Function objects in C++ (C++11)

I am reading about boost::function and I am a bit confused about its use and its relation to other C++ constructs or terms I have found in the documentation, e.g. here.
In the context of C++ (C++11), what is the difference between an instance of boost::function, a function object, a functor, and a lambda expression? When should one use which construct? For example, when should I wrap a function object in a boost::function instead of using the object directly?
Are all the above C++ constructs different ways to implement what in functional languages is called a closure (a function, possibly containing captured variables, that can be passed around as a value and invoked by other functions)?
A function object and a functor are the same thing; an object that implements the function call operator operator(). A lambda expression produces a function object. Objects with the type of some specialization of boost::function/std::function are also function objects.
Lambda are special in that lambda expressions have an anonymous and unique type, and are a convenient way to create a functor inline.
boost::function/std::function is special in that it turns any callable entity into a functor with a type that depends only on the signature of the callable entity. For example, lambda expressions each have a unique type, so it's difficult to pass them around non-generic code. If you create an std::function from a lambda then you can easily pass around the wrapped lambda.
Both boost::function and the standard version std::function are wrappers provided by the li­brary. They're potentially expensive and pretty heavy, and you should only use them if you actually need a collection of heterogeneous, callable entities. As long as you only need one callable entity at a time, you are much better off using auto or templates.
Here's an example:
std::vector<std::function<int(int, int)>> v;
v.push_back(some_free_function); // free function
v.push_back(&Foo::mem_fun, &x, _1, _2); // member function bound to an object
v.push_back([&](int a, int b) -> int { return a + m[b]; }); // closure
int res = 0;
for (auto & f : v) { res += f(1, 2); }
Here's a counter-example:
template <typename F>
int apply(F && f)
{
return std::forward<F>(f)(1, 2);
}
In this case, it would have been entirely gratuitous to declare apply like this:
int apply(std::function<int(int,int)>) // wasteful
The conversion is unnecessary, and the templated version can match the actual (often unknowable) type, for example of the bind expression or the lambda expression.
Function Objects and Functors are often described in terms of a
concept. That means they describe a set of requirements of a type. A
lot of things in respect to Functors changed in C++11 and the new
concept is called Callable. An object o of callable type is an
object where (essentially) the expression o(ARGS) is true. Examples
for Callable are
int f() {return 23;}
struct FO {
int operator()() const {return 23;}
};
Often some requirements on the return type of the Callable are added
too. You use a Callable like this:
template<typename Callable>
int call(Callable c) {
return c();
}
call(&f);
call(FO());
Constructs like above require you to know the exact type at
compile-time. This is not always possible and this is where
std::function comes in.
std::function is such a Callable, but it allows you to erase the
actual type you are calling (e.g. your function accepting a callable
is not a template anymore). Still calling a function requires you to
know its arguments and return type, thus those have to be specified as
template arguments to std::function.
You would use it like this:
int call(std::function<int()> c) {
return c();
}
call(&f);
call(FO());
You need to remember that using std::function can have an impact on
performance and you should only use it, when you are sure you need
it. In almost all other cases a template solves your problem.

What Does "Overloaded"/"Overload"/"Overloading" Mean?

What does "Overloaded"/"Overload" mean in regards to programming?
It means that you are providing a function (method or operator) with the same name, but with a different signature.
For example:
void doSomething();
int doSomething(string x);
int doSomething(int a, int b, int c);
Basic Concept
Overloading, or "method overloading" is the name of the concept of having more than one methods with the same name but with different parameters.
For e.g. System.DateTime class in c# have more than one ToString method. The standard ToString uses the default culture of the system to convert the datetime to string:
new DateTime(2008, 11, 14).ToString(); // returns "14/11/2008" in America
while another overload of the same method allows the user to customize the format:
new DateTime(2008, 11, 14).ToString("dd MMM yyyy"); // returns "11 Nov 2008"
Sometimes parameter name may be the same but the parameter types may differ:
Convert.ToInt32(123m);
converts a decimal to int while
Convert.ToInt32("123");
converts a string to int.
Overload Resolution
For finding the best overload to call, compiler performs an operation named "overload resolution". For the first example, compiler can find the best method simply by matching the argument count. For the second example, compiler automatically calls the decimal version of replace method if you pass a decimal parameter and calls string version if you pass a string parameter. From the list of possible outputs, if compiler cannot find a suitable one to call, you will get a compiler error like "The best overload does not match the parameters...".
You can find lots of information on how different compilers perform overload resolution.
A function is overloaded when it has more than one signature. This means that you can call it with different argument types. For instance, you may have a function for printing a variable on screen, and you can define it for different argument types:
void print(int i);
void print(char i);
void print(UserDefinedType t);
In this case, the function print() would have three overloads.
It means having different versions of the same function which take different types of parameters. Such a function is "overloaded". For example, take the following function:
void Print(std::string str) {
std::cout << str << endl;
}
You can use this function to print a string to the screen. However, this function cannot be used when you want to print an integer, you can then make a second version of the function, like this:
void Print(int i) {
std::cout << i << endl;
}
Now the function is overloaded, and which version of the function will be called depends on the parameters you give it.
Others have answered what an overload is. When you are starting out it gets confused with override/overriding.
As opposed to overloading, overriding is defining a method with the same signature in the subclass (or child class), which overrides the parent classes implementation. Some language require explicit directive, such as virtual member function in C++ or override in Delphi and C#.
using System;
public class DrawingObject
{
public virtual void Draw()
{
Console.WriteLine("I'm just a generic drawing object.");
}
}
public class Line : DrawingObject
{
public override void Draw()
{
Console.WriteLine("I'm a Line.");
}
}
An overloaded method is one with several options for the number and type of parameters. For instance:
foo(foo)
foo(foo, bar)
both would do relatively the same thing but one has a second parameter for more options
Also you can have the same method take different types
int Convert(int i)
int Convert(double i)
int Convert(float i)
Just like in common usage, it refers to something (in this case, a method name), doing more than one job.
Overloading is the poor man's version of multimethods from CLOS and other languages. It's the confusing one.
Overriding is the usual OO one. It goes with inheritance, we call it redefinition too (e.g. in https://stackoverflow.com/users/3827/eed3si9n's answer Line provides a specialized definition of Draw().