www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - std.format.formattedRead docs example does not work with a string

reply ParticlePeter <ParticlePeter gmx.de> writes:
Example from docs:
string s = "hello!124:34.5";
string a;
int b;
double c;
formattedRead(s, "%s!%s:%s", &a, &b, &c);
assert(a == "hello" && b == 124 && c == 34.5);

now changing the first formattedRead argument to a string literal:
formattedRead("hello!124:34.5", "%s!%s:%s", &a, &b, &c);

results in this compiler error:
Error: template std.format.formattedRead cannot deduce function 
from argument types !()(string, string, string*, int*, double*), 
candidates are:
..\..\src\phobos\std\format.d(588,6):
std.format.formattedRead(R, Char, S...)(ref R r, const(Char)[] 
fmt, S args)

I am not getting the point that in both cases the argument is a 
string, but in the first case it is interpreted as a Range, and 
in the second case not. Why?
Mar 31 2016
parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Thu, Mar 31, 2016 at 06:23:21PM +0000, ParticlePeter via Digitalmars-d-learn
wrote:
 Example from docs:
 string s = "hello!124:34.5";
 string a;
 int b;
 double c;
 formattedRead(s, "%s!%s:%s", &a, &b, &c);
 assert(a == "hello" && b == 124 && c == 34.5);
 
 now changing the first formattedRead argument to a string literal:
 formattedRead("hello!124:34.5", "%s!%s:%s", &a, &b, &c);
 
 results in this compiler error:
 Error: template std.format.formattedRead cannot deduce function from
 argument types !()(string, string, string*, int*, double*), candidates are:
 ..\..\src\phobos\std\format.d(588,6):
 std.format.formattedRead(R, Char, S...)(ref R r, const(Char)[] fmt, S args)
 
 I am not getting the point that in both cases the argument is a
 string, but in the first case it is interpreted as a Range, and in the
 second case not.
 Why?
Because in the second case the string is an rvalue, whereas in the first case it gets stored in a variable first, so it's an lvalue. The first parameter of formattedRead is 'ref', meaning that it requires an lvalue. (Arguably, it should be `auto ref` instead, then literals would work, but that belongs in an enhancement request.) T -- Государство делает вид, что платит нам зарплату, а мы делаем вид, что работаем.
Mar 31 2016
parent ParticlePeter <ParticlePeter gmx.de> writes:
On Thursday, 31 March 2016 at 18:25:45 UTC, H. S. Teoh wrote:
 On Thu, Mar 31, 2016 at 06:23:21PM +0000, ParticlePeter via 
 Digitalmars-d-learn wrote:
 Example from docs:
 string s = "hello!124:34.5";
 string a;
 int b;
 double c;
 formattedRead(s, "%s!%s:%s", &a, &b, &c);
 assert(a == "hello" && b == 124 && c == 34.5);
 
 now changing the first formattedRead argument to a string 
 literal: formattedRead("hello!124:34.5", "%s!%s:%s", &a, &b, 
 &c);
 
 results in this compiler error:
 Error: template std.format.formattedRead cannot deduce 
 function from
 argument types !()(string, string, string*, int*, double*), 
 candidates are:
 ..\..\src\phobos\std\format.d(588,6):
 std.format.formattedRead(R, Char, S...)(ref R r, const(Char)[] 
 fmt, S args)
 
 I am not getting the point that in both cases the argument is a
 string, but in the first case it is interpreted as a Range, 
 and in the
 second case not.
 Why?
Because in the second case the string is an rvalue, whereas in the first case it gets stored in a variable first, so it's an lvalue. The first parameter of formattedRead is 'ref', meaning that it requires an lvalue. (Arguably, it should be `auto ref` instead, then literals would work, but that belongs in an enhancement request.) T
Ok, thanks, that makes sense. I would add that the compiler should mention that a ref value is required, this would have helped to understand the issue.
Mar 31 2016