Jump to page: 1 2
Thread overview
C++ istream / ostream equivalent ?
Dec 01, 2010
vincent picaud
Dec 01, 2010
Matthias Pleh
Dec 01, 2010
vincent picaud
Dec 01, 2010
Matthias Pleh
Dec 02, 2010
vincent picaud
Dec 02, 2010
Pelle Månsson
Dec 02, 2010
vincent picaud
Dec 02, 2010
Ali Çehreli
Dec 01, 2010
Dmitry Olshansky
Dec 01, 2010
Matthias Pleh
Dec 01, 2010
Ali Çehreli
Dec 01, 2010
Jonathan M Davis
Dec 01, 2010
Matthias Pleh
Dec 01, 2010
bearophile
December 01, 2010
Is there a canonical way to take into account a new type for I/O using the std phobos library ?

To be clear I do not know how to translate something like this (in C++)  in D :

#include <iostream>

class A {};

std::ostream& operator<<(std::ostream& out,const A& a)
{
  out << "\nscreen output routine here\n";
  return out;
}

int main()
{
  A a;
  std::cout << a;
}

Do I have to overload some writeln functions ?

any help is welcome :)
December 01, 2010
Am 01.12.2010 16:51, schrieb vincent picaud:
> Is there a canonical way to take into account a new type for I/O using the std phobos library ?
>
> To be clear I do not know how to translate something like this (in C++)  in D :
>
> #include<iostream>
>
> class A {};
>
> std::ostream&  operator<<(std::ostream&  out,const A&  a)
> {
>    out<<  "\nscreen output routine here\n";
>    return out;
> }
>
> int main()
> {
>    A a;
>    std::cout<<  a;
> }
>
> Do I have to overload some writeln functions ?
>
> any help is welcome :)

I would make it this way:

module test;

import std.stdio;

class A{}
class B{ string toString() {return "screen output routine here";}}

int main(string[] args)
{
    A a=new A;
    B b=new B;
    writeln(a.toString());
    writeln(b.toString());
    return 0;
}

output:
> test.A
> screen output routine here

Base-class of all classes is object with have a default-toString() method, which gives the module.classname.
So you can overwrite this method.
December 01, 2010
Matthias Pleh Wrote:

> Am 01.12.2010 16:51, schrieb vincent picaud:
> > Is there a canonical way to take into account a new type for I/O using the std phobos library ?
> >
> > To be clear I do not know how to translate something like this (in C++)  in D :
> >
> > #include<iostream>
> >
> > class A {};
> >
> > std::ostream&  operator<<(std::ostream&  out,const A&  a)
> > {
> >    out<<  "\nscreen output routine here\n";
> >    return out;
> > }
> >
> > int main()
> > {
> >    A a;
> >    std::cout<<  a;
> > }
> >
> > Do I have to overload some writeln functions ?
> >
> > any help is welcome :)
> 
> I would make it this way:
> 
> module test;
> 
> import std.stdio;
> 
> class A{}
> class B{ string toString() {return "screen output routine here";}}
> 
> int main(string[] args)
> {
>      A a=new A;
>      B b=new B;
>      writeln(a.toString());
>      writeln(b.toString());
>      return 0;
> }
> 
> output:
>  > test.A
>  > screen output routine here
> 
> Base-class of all classes is object with have a default-toString()
> method, which gives the module.classname.
> So you can overwrite this method.

Thank you for your reply and yes that works :)

Now i m facing with the following problem, what is the trick for input stream ?

( something like

std::istream& operator>>(std::istream& in,A& a)
{
  //  A.someData << in;
  return in;
}

in C++ )

I m thinking of the situation when we want to load some data from a file.

The toString() trick is okay for saving the object... but how to load it back (something like fromString(char[]) would do the job but it does not exist in Object) ?

Anyway thank you, you solved half of my problem :)




December 01, 2010
On 01.12.2010 20:11, Matthias Pleh wrote:
> Am 01.12.2010 16:51, schrieb vincent picaud:
>> Is there a canonical way to take into account a new type for I/O using the std phobos library ?
>>
>> To be clear I do not know how to translate something like this (in C++)  in D :
>>
>> #include<iostream>
>>
>> class A {};
>>
>> std::ostream&  operator<<(std::ostream&  out,const A&  a)
>> {
>>    out<<  "\nscreen output routine here\n";
>>    return out;
>> }
>>
>> int main()
>> {
>>    A a;
>>    std::cout<<  a;
>> }
>>
>> Do I have to overload some writeln functions ?
>>
>> any help is welcome :)
>
> I would make it this way:
>
> module test;
>
> import std.stdio;
>
> class A{}
> class B{ string toString() {return "screen output routine here";}}
>
> int main(string[] args)
> {
>     A a=new A;
>     B b=new B;
>     writeln(a.toString());
>     writeln(b.toString());

Or even more implicit version, since writeln and the likes recognize toString:
writeln(a);
writeln(b);

>     return 0;
> }
>
> output:
> > test.A
> > screen output routine here
>
> Base-class of all classes is object with have a default-toString() method, which gives the module.classname.
> So you can overwrite this method.
Well there is a relatively new proposal which aims to replace toString with more eficient and flexible function (and was generally accepted):
http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9

-- 
Dmitry Olshansky

December 01, 2010
Matthias Pleh wrote:

> class B{ string toString() {return "screen output routine here";}}

Isn't the 'override' keyword required? (Perhaps required only in D2?)

I find string.format very helpful in toString() member functions.

Finally, I still don't know whether the 'const'ness of the member function is required, allowed, or completely wrong. :)

import std.string;

class A
{
    override string toString() const
    {
        return format("My %s formatted string: %s", "lovely", 42);
    }
}

Ali
December 01, 2010
>
> Thank you for your reply and yes that works :)
>
> Now i m facing with the following problem, what is the trick for input stream ?
>
> ( something like
>
> std::istream&  operator>>(std::istream&  in,A&  a)
> {
>    //  A.someData<<  in;
>    return in;
> }
>
> in C++ )
>
> I m thinking of the situation when we want to load some data from a file.
>
> The toString() trick is okay for saving the object... but how to load it back (something like fromString(char[]) would do the job but it does not exist in Object) ?
>
> Anyway thank you, you solved half of my problem :)
>
>

Ther are many posibilities, depending on your further needs! Just have a look at the online dokumentation:
http://www.digitalmars.com/d/2.0/phobos/phobos.html

But my first try would be such ..
(note: I've leaved out error-handling ...)

module test;

import std.stdio;
import std.file;

class A
{
    void writeToFile()  { std.file.write("sample.txt",someData);   }
    void readFromFile() { someData=cast(string)read("sample.txt"); }
    void clear()        { someData="n/A\n"; }
    string toString()   { return someData;  }
private:
    string someData="Just some data.
With anohter line of date.
Even more data.!";	
}

int main(string[] args)
{
	A a=new A;
	a.writeToFile();
	a.clear();
	writeln(a);
	a.readFromFile();
	writeln(a);
	return 0;
}
December 01, 2010
>
> Or even more implicit version, since writeln and the likes recognize
> toString:
> writeln(a);
> writeln(b);
>

[...]

> Well there is a relatively new proposal which aims to replace toString
> with more eficient and flexible function (and was generally accepted):
> http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9
>

thanks
I wasn't aware of that. :)
December 01, 2010
On Wednesday, December 01, 2010 11:40:11 Ali Çehreli wrote:
> Matthias Pleh wrote:
>  > class B{ string toString() {return "screen output routine here";}}
> 
> Isn't the 'override' keyword required? (Perhaps required only in D2?)
> 
> I find string.format very helpful in toString() member functions.
> 
> Finally, I still don't know whether the 'const'ness of the member function is required, allowed, or completely wrong. :)
> 
> import std.string;
> 
> class A
> {
>      override string toString() const
>      {
>          return format("My %s formatted string: %s", "lovely", 42);
>      }
> }
> 
> Ali

override is required if you compile with -w. If you don't use -w, the compiler won't complain, but I'm not sure that it actually overrides the function in that case. So, yes override should be there.

Object's toString() is not currently const-correct. It isn't const. So, currently, when overriding toString(), you don't have to make it const. However, you _can_ make it const if you want to (and honestly, Object's toString() _should_ be const; it's just among the changes that need to be made to Object to make it properly const-correct: http://is.gd/i3KUJ ). Making a non-const function const when overriding it is adding guarantees, not loosening them, so it works.

Be forewarned, however, that because of bug http://is.gd/i3Lc2 ), _struct_'s toString() cannot be const (or at least, you need a non-const version in addition to a const one if you have a const one). Classes don't have that problem though.

- Jonathan M Davis
December 01, 2010
Am 01.12.2010 20:59, schrieb Jonathan M Davis:
> override is required if you compile with -w. If you don't use -w, the compiler
> won't complain, but I'm not sure that it actually overrides the function in that
> case. So, yes override should be there.

I've just tried it out. It is really overridden, even if the override keyword is missing.
But the cool thing with override is, when you use it, but mistpyed the methodname or someone else changed one of the methods, the compiler know, you wanted to override something, but there isn't anymore to override!

So yes, you're right, override should be used!!
December 01, 2010
Jonathan M Davis:

> override is required if you compile with -w. If you don't use -w, the compiler won't complain, but I'm not sure that it actually overrides the function in that case. So, yes override should be there.

override will become obligatory, Andrei and Walter agree with this change, so always (when possible) use it. See also bug 3836.

Bye,
bearophile
« First   ‹ Prev
1 2