>> On 13.09.2016 19:17, Ike Naar wrote:
>>>> Not quite the same. E.g.
>>> std::string s{5, 'x'};
>>> does not mean the same as
>>> std::string s(5, 'x');
>>> What's the differenece?
>> The first gives a string with the two values char(5) and char('x').
>> The second gives a string with five char('x') values.
>> This is also a problem with `std::vector`.
>
> Well, "problem"?
>
> It sounded like this to me:
>
> ||What's the difference between "5+2" and "5-2"?
> |
> |The first one gives 7 and the second one 3.
> |
> |This is also a problem with "*" and "/".
In most cases the two constructor call notations give the same result.
It's usually unexpected when they don't mean the same, because it isn't
clear from the calling code, and it depends on the concrete classes.
That's a problem.
And in the standard library it's mainly a problem with
`std::basic_string` and `std::vector`.
The fix direction I proposed addressed the lack of clarity in the
calling code.
> I sometimes used something like this:
>
> #include <iostream>
> #include <initializer_list>
> #include <ostream>
> #include <string>
>
> using namespace ::std::literals;
>
> struct string : public ::std::string
> { //using ::std::string::string;
> string( size_type const n, char const c ):
> ::std::string( n, c ){}; };
>
> struct stringfromlist : public ::std::string
> { stringfromlist( char const n, char const c ):
> ::std::string{ n, c }{};
> stringfromlist( ::std::initializer_list< char > const list ):
> ::std::string( list ){}; };
>
> void p( ::std::string const s ) { ::std::cout << s << '\n'; }
> int main ()
> { { string s( 2, 65 ); ::std::cout << s << '\n'; }
> { string s{ 2, 65 }; ::std::cout << s << '\n'; }
> { stringfromlist s( 2, 65 ); ::std::cout << s << '\n'; }
> { stringfromlist s{ 2, 65 }; ::std::cout << s << '\n'; }}
>
> Above, »string ... 2, 65« always means »two 'A'«, and
> »stringfromlist ... 2, 65« always means »(char)2« and »'A'«.
To my eyes all these prefixes are visual noise that make the code pretty
unreadable, but I have talked with Norwegian programmers who claim that
on the contrary, when they get used to it the prefixes increase
readability for them. I can't fathom how. But.
Ditto for the indentation convention, I can't see how you can get used
to that at all. Do tools such as AStyle support that?
Anyway, one technical problem with this approach is that the derived
classes can affect overload resolution so that e.g. operators are not
found. I was surprised to find that unqualified `swap` worked with
arguments of the two different derived classes. Someone will no doubt
find an explanation for that apparent weirdness. It's both about the ADL
and about the template argument deduction. But as an example that works,
in the sense that it fails to compile, consider:
template< class Type >
void foo( Type&, Type& ) {}
int main ()
{ {string a( 1, 'A' ); stringfromlist b( 2, 'A' ); foo( a, b ); }}