It should work all the cases that *std::initializer_list* do.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Changing the vector class will not necessarily solve inherent ambiguity because initializer list has preference over constructor calls.
Initializer can always be called by mistake if the intended parameters are the same type, although such cases are small I believe but having such a syntax will make the programmer's intention clear
Well - very simple. You just need to replace std::initializer_list with std::array.
събота, 18 април 2015 г., 23:53:42 UTC+3, Thiago Macieira написа:On Saturday 18 April 2015 09:25:35 Alexander Marinov wrote:
> I would rather suggest removing 'std::initializer_list' as it can be fully
> replaced by using arrays. It only creates confusion and pollutes the new
> initialization syntax.
Please explain how initializer_list can be replaced by arrays.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
Since we are throwing wild, hard or impossible to do ideas around 'std::initializer_list', what about making it a bit more cumbersome to use:
std::vector<int> a{{1, 2}}; // vector with contents [ 1, 2 ]
std::vector<int> b{1, 2}; // vector with contents [ 2 ]
Since initializer list currently takes precedence, then adapting {{}} for strict initialization would be better.
It will eventually even make more sense in my opinion because {{}} can lead to subtle confusion when working with maps as that can easily lead to three { for the first key-value pair
--
On 2015–04–20, at 4:36 PM, David Rodríguez Ibeas <dib...@ieee.org> wrote:Since we are throwing wild, hard or impossible to do ideas around 'std::initializer_list', what about making it a bit more cumbersome to use:
std::vector<int> a{{1, 2}}; // vector with contents [ 1, 2 ]
std::vector<int> b{1, 2}; // vector with contents [ 2 ]
Why? Just to bother people... not really. This would make the use of initializer lists slightly more cumbersome (not much, once you are typing the first {, pressing twice is not a huge deal and the same goes for }) but allow clearer distinction of this versus non-initializer lists arguments,
which would be helpful in the context of some papers like N4029, by allowing the selection of a non-initializer list constructor when an initializer-list is present:
A g() {
return {{ 1 }}; // initializer_list constructor
}
A h() {
return { 1 }; // int constructor
}
An alternative syntax to consider would be the explosed-initializer-list which will prefer to expand its elements into separate constructor arguments
}a,b,c{
Sorry, I meant using trailing comma for disambiguation not making the latter always a constructor call.
That is why I used vector<int> as an example
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
On 2016–02–19, at 7:39 AM, Ville Voutilainen <ville.vo...@gmail.com> wrote:On 19 February 2016 at 01:35, Olanrewaju Adetula <jspha...@gmail.com> wrote:how about differentiating between initializer list and constructor by
allowing for trailing comma after after the last element for an initializer
list with a compile time error if no initializer list is found
vector<int> ai = { 5, }; //initializer list
vector<int> ai = { 5 }; //constructor call
That was suggested at one point as a way to disambiguate, but it got rejected
as a disambiguation means. It might be possible to try getting such a
tweak accepted.This particular tweak is a massive breaking change.Looking back over this thread, I see neither a clear motivation nor a mention of the current pattern: Braces tend to represent value aggregation and parens tend to represent computation by a function.
template<typename ...Ts>
T emplace(Ts&& ...ts)
{
return T{std::forward<Ts>(ts)};
}
If the motivation is to get a constructor call without naming the type, how about the syntax auto(expression-list) to deduce (and explicitly cast to) a type from the given context?The debate about implicit vs. explicit was contentious. As an implicit-to-explicit operator, this might help to find some middle ground.struct very_long_name {explicit very_long_name( int, int, int );very_long_name( std::initializer_list< int > );};template< typename t >void f( t && );s factory() {return { 1, 2, 3 }; // initializer listreturn auto( 1, 2, 3 ); // constructorreturn flag? very_long_name( 1, 2, 3 ) : auto{ 1, 2, 3 }; // either initializer list or constructorf( auto{ 1, 2, 3 } ); // shortcut for initializer_list}The syntax auto(expr) has also been suggested to perform lvalue-to-rvalue conversion, but that can be done well enough (and with a better name) by a library facility.
On Thursday, February 18, 2016 at 8:59:54 PM UTC-5, David Krauss wrote:Looking back over this thread, I see neither a clear motivation nor a mention of the current pattern: Braces tend to represent value aggregation and parens tend to represent computation by a function.
Is that "the current pattern"? I thought the whole point of having braced-init-lists was to allow aggregation and construction to be identical. It is called "Uniform Initialization", after all.
The motivation is to be able to do this:
template<typename ...Ts>
T emplace(Ts&& ...ts)
{
return T{std::forward<Ts>(ts)};
}
Actually, this reminds me of a one-off idea I had at one point to allow `return <braced-init-list>` to work. I suggested `explicit <braced-init-list>`, but `auto {}` could work too.
We have two problems nowadays with braced-init-lists:
1) Unable to call explicit constructors without naming the type.
2) Initializer_list constructors taking priority when there is a conflict.
Having `auto {}` do both of these would probably be a good idea. I justify joining these two problems because most initializer_list constructors aren't marked explicit.
This should also allow you to do:
T t auto{};
That is, direct-list-initialization. Again, as a way to bypass initializer_list constructors.
On Sun, Feb 21, 2016 at 5:58 AM, Nicol Bolas <jmck...@gmail.com> wrote:On Thursday, February 18, 2016 at 8:59:54 PM UTC-5, David Krauss wrote:Looking back over this thread, I see neither a clear motivation nor a mention of the current pattern: Braces tend to represent value aggregation and parens tend to represent computation by a function.
Is that "the current pattern"? I thought the whole point of having braced-init-lists was to allow aggregation and construction to be identical. It is called "Uniform Initialization", after all.We have identical syntax for aggregation and construction as long as they don't conflict. When they do conflict, we have different syntaxes to disambiguate. It's your choice whether to maximize use of braces and relegate parens to special cases of ambiguity, or to generalize the pre-C++11 patterns and use braces for constructors only which perform something like conceptual aggregation.
We have two problems nowadays with braced-init-lists:
1) Unable to call explicit constructors without naming the type.
2) Initializer_list constructors taking priority when there is a conflict.
Having `auto {}` do both of these would probably be a good idea. I justify joining these two problems because most initializer_list constructors aren't marked explicit.
This should also allow you to do:
T t auto{};
That is, direct-list-initialization. Again, as a way to bypass initializer_list constructors.Any brace syntax that bypasses initializer_list would be extremely confusing.
Especially one that appears to only be pulling in some harmless deduction.If it hurts when you use braces absolutely everywhere, then don't do that.
(The same goes for Almost Always Auto.)
Such rules work well with unsurprising, simple programs. Once one strays from value semantics, the grammatical vocabulary needs to increase. (And besides being new, T t auto{} would be equally non-uniform and un-generic as using parens instead of braces!)
For std::vector, for example, there's simply no need to tell a beginner about the constructors other than std::initializer_list. It works fine to default-construct and then call resize or insert. If it's actually a vector of vectors, then write a loop — that's actually more efficient than duplicating a prototype vector. Shortcuts and terseness naturally tend to conflict with uniformity. Maximizing one might mean sacrificing the other.
Nonsense. If uniform initialization had been done correctly, if it had been made uniform, we wouldn't have to sacrifice anything. Creating an array with a vector would simply be `vector<int> v = {{1, 2, 3}};` One set of extra brackets makes all the difference. If that had been how C++11 shipped, people would simply have gotten used to using the double braces for that. Generic could would be able to distinguish between constructor initialization and initializer list initialization.
It would have been uniform initialization.
We also wouldn't need special brace-elision rules to make `array<int, 3> a = {1, 2, 3};` work. The only place where you wouldn't use a double-brace would be an actual language array. And people should just stop using those ;)