Talk:C++11/Archive 1

From Wikipedia, the free encyclopedia
Jump to: navigation, search
Archive 1 Archive 2

Rewrite

The article is riddled with typoes and strange terminology. I fixed a few, but the task is daunting as many of the sentences are difficult for me to undestand what they were meant to say (although I can guess a few, My knowledge in the subject is limited, so I won't even try). --M.A. 21:02, 24 November 2006 (UTC)

Yes, I'm sorry for my bad English. If you take my some examples of incomprehensible text, we could try to fix it. NOTE: bernoulli_distribution and poisson_distribution are lowercase, as they are been defined by "ISO/IEC DTR 19768 (June 24, 2005) Doc No: N1836 Draft Technical Report on C++ Library Extensions".--Gildos 19:13, 26 November 2006 (UTC)
Your contribution is appreciated and the article does treat much (everything?) of the proposal as of now! I applaud the effort you've put into it! Still, though, Acolyte of Discord's comments remains valid: the article is in need of thorough copy-editing since the language is partially only semi-grammatical resulting in ambiguous propositions, unnecessarily convolute constructions, statements reading as POV, and an often awkward read. Unfortunately, I too dare not touch it since I'm not familiar enough with the topic and fear that I might introduce untruths, which would be worse than problematic language. Mikademus 18:17, 27 November 2006 (UTC)
The article doesn't treat everything of the proposal but only principal features, as you can see here and in the Technical Report 1 --Gildos 19:28, 27 November 2006 (UTC)
I have done quite a bit of copyediting of the article today to clean up some of the awkward wording. However, there were some sentences I simply couldn't parse. In particular, in the "Extensible random number facility" section, I have no idea what "Apparent casualness is due only from limited perception of users" means. If anyone can figure that out and reword it, it would be a help. Julesd 03:41, 8 July 2007 (UTC)
Maybe they meant "causality" not "casualness"? Alternately, maybe they meant that rand() seems simple (and good enough) to users only because users don't fully understand the complicated nature of RNG/distributions? I also find it hard to understand the original meaning 24.17.110.123 11:26, 18 August 2007 (UTC)

Aspect Oriented Software?

Won't the new version of C++ include AOS (Aspect Oriented Software)? (This is more a wish than a discussion).

Not according to this document, but I'm not close enough to the topic to say for certain. --Gabriel "Jarl" Sjoberg 07:38, 2 January 2007 (UTC)

Strange paragraph

This concerns a paragraph which I (EatMyShortz) deleted:

I have referenced now the piece of article you have deleted. The document is The Design of C++0x: Reinforcing C++’s proven strengths, while moving into the future at the paragraph of Design and Evolution. If you find unreferenced parts use comments or the discussion page like the other user please. I am available to clarify all your doubts about this article. --Gildos 19:41, 8 January 2007 (UTC)
Hi Gildos. Well I found the paragraph which was paraphrased in the above article. However, just because it's referenced doesn't give it a neutral point of view. This article is an opinion piece, written by the language's author. The statement (and the paraphrased version of it here) is basically a sweeping opinion of one language designer, about language design in general, as well as a prediction of what "will" provide the greatest benefits. It has no specific relevance to C++, and is non-encyclopedic. Therefore, I am removing it again. Please don't add it back unless you have a specific reason for it to be here. (And if you must revert, please do so to my previous version, where I added a link in the reference). —EatMyShortz 11:34, 10 January 2007 (UTC)

You can trust or don't trust it, but it is not the point of view of one language designer, it is a line guide of the C++ Language Committee. If you don't like the way it was writed,rewrite it please. Deletion is a bad solution. --Gildos 14:53, 10 January 2007 (UTC)

Do you prefer this way?

The designers of a language can be obsessed with notation problems of small relevance, neglecting more meaningful language features that may allow new programming styles to develop. The C++ Language Committee believe that a good feature provides a direct response to a problem; it does not significantly interact with other features of the language and typically has a reduced logical expression, leading to concise portions of code. The greatest benefits will come from solutions that allow the programmer to resolve a problem and to better organize the code, as happened with the introduction of object-oriented programming and generic programming (templates).

I'm waiting the opinion of other users. --Gildos 14:53, 10 January 2007 (UTC)

"It has no specific relevance to C++, and is non-encyclopedic."

You must be joking, sir. Either that, or you really have no idea how the committee works. BS's opinion is extremely respected. Of course it's not just his "baby", he can't decide anything alone.

But throwing away BS's text like that is silly. It's obviously relevant to C++ and obviously encyclopedic.

I think you are just trolling. Find another game, please.

--212.27.60.48 (talk) 07:44, 11 February 2009 (UTC)

General Purpose Smart Pointers

I did what I could to rewrite the section about smart pointers, but I wasn't sure what to say about the weak_ptr template, since I can't figure out why that would be used instead of a regular pointer, if what I googled about the topic was any use. Using my own judgement, the only purposes of a weak_ptr would be to prevent the implicit/automatic destruction of objects, or have a reference that would be automatically nulled when the owner was destroyed, but I couldn't find any evidence for either theory.--Prgrmr@wrk 07:22, 23 January 2007 (UTC)

The main goal of the weak pointer is to reference an object without influence its cicle of life. Garbage Collection is not provided in the proposal of General Purpose Smart Pointers as you can see in A Proposal to Add General Purpose Smart Pointers to the Library Technical Report (Revision 1).--Gildos 11:40, 23 January 2007 (UTC)
A regular pointer is just a pointer to an area of memory - after the object it is pointing to has been deleted, the regular pointer will still seem fine to the naive user, but will be pointing to god-knows-what. A weak_ptr has no effect on the existence of the object it is referring to, but it does know when the object has been deleted, and prevents the user from accessing it thereafter.

Indeed, they are very few uses for weak_ptr. And for the few cases where they can be used, it's usually suboptimal.

Most people who pretend weak_ptr is extremely useful simply don't understand anything about smart pointers; they confuse them with gc (as in Boehm gc) where every normal pointer (T*) is followed by the gc system and is thus a strong pointer.

Most examples of use of weak_ptr are totally bogus. It's frighting! I have been (almost) kicked of a forum for saying that weak_ptr wasn't that useful! --212.27.60.48 (talk) 07:38, 11 February 2009 (UTC)

2.4.2 Lambda Expression

It says that "As a shortcut, closure variables refering to local variables can be defined as:" and then comes the following code:

int total = 0;
<>(x: &total) {total += x}

Which should be equal to

int total = 0;
<>(x: auto &total = total) {total += x}

I was wondering if not the ":" should be a comma (","), so the code should be

int total = 0;
<>(x, &total) {total += x}

and

int total = 0;
<>(auto x, auto &total = total) {total += x}

81.233.131.203 19:57, 10 September 2007 (UTC)

No, the ':' is there to separate parameters to the lambda from references to variables outside the lambda. 'x' is a parameter, 'total' is a local variable that is referenced by the lambda code. The '&' means that the lambda closure will contain a reference to the local variable 'total', it could be done without the '&' as well in which case the closure would have it's own copy of the variable (and the whole lambda would be a no-op).
213.100.20.12 02:21, 12 October 2007 (UTC)

Article is Too Long

The article has been flagged as too long. Granted, this is probably meaningless because most people who might be inclined to shorten it can't understand and properly summarize the material. So there isn't much worry about the lay person coming along and ransacking it. However, it is very long. Should we make some of the sections smaller, turning some of the detailed explanations into summaries? Korval (talk) 19:11, 27 December 2007 (UTC)

When I start to write this article, I planned that in 2009, at the release of new C++ standard, it will be split in many sub article one for every utilty like other existing utilities of actual C++. I think this is the right way to split this article. At now every new article should be an upcoming software and the article C++0x will be a summarise of all the modifications. It's no so simple, because references may be split for every article. If the community like this way of splitting I start to do that, with the hope that no new article will be deleted. --Gildos (talk) 02:38, 29 December 2007 (UTC)

On the wrapper reference

The example used to motivate the introduction of wrapper references is:

// This function will obtain a reference to the parameter 'r' and increase it.
void f( int &r )  { r++ ; }

// Template function.
template<class F, class P>void g( F f, P t )  { f(t) ; }

int main()
{
  int i = 0 ;
  g( f, i ) ;  // 'g<void ( int &r ), int>' is instantiated
               // then 'i' will not be modified.
  cout << i << endl ;  // Output -> 0

  g( f, ref(i) ) ;  // 'g<void(int &r),reference_wrapper<int>>' is instanced
                    // then 'i' will be modified.
  cout << i << endl ;  // Output -> 1
}

Won't we achieve the same effect by simply defining g with the second argument as a reference, like this:

template<class F, class P>void g( F f, P& t )  { f(t) ; }

Jorram (talk) 12:07, 16 January 2008 (UTC)

You 're in right but with
template< class F, class P > void g( F f, P& t )  { f(t) ; }
you cannot decide if parameter t will be modified or not. Every intallation of template g will modify the parameter. Remember, it's only a stupid example. Bye. --Gildos (talk) 12:39, 19 January 2008 (UTC)
Equally importantly, what if you don't have control over g's definition? For example, Boost.Bind/TR1.Bind can't take references as parameters to be bound to functions, because that's how it is defined. It has to take reference wrappers if you want to pass a reference. In many ways, it exists for the same reason that something like TR1.Bind does: so that you can do something with someone elses code that would otherwise be syntactically impossible. Bind can turn a multi-parameter function into a function of 1 parameter suitable for use in a standard algorithm. Reference wrappers turn a copy-style template parameter into a reference-style parameter. All without having to change the actual interface itself.Korval (talk) 02:51, 22 January 2008 (UTC)

Color tags for c++0x/TR2/abandonned

It would be useful to add an icon or a color tag or something else to easily see what will be available in C++0x, what would be available for the next revision (TR2?) and what is abandoned (if any in this page). As I'm not a specialist (about the subject and about wiki edition standards), I'll do it myself now, but maybe will try in some weeks if i found time and energy to parse the last reports. Klaim (talk) 00:26, 20 February 2008 (UTC)

Nothing on this page should be anything that has been specifically remanded to a future TR or language revision. Everything on the page should be exactly what is expected to be in C++0x. If, as standardization approaches, something is remanded to later revisions, then it should be removed from this page, not color coded. Korval (talk) 00:46, 20 February 2008 (UTC)
Then i guess the garabage collector part should be removed? MJKlaim (talk) 01:08, 20 February 2008 (UTC)

Initializer lists to initialize std::vector?

This paragraph in the initializer list part suggest that a container like a std::vector cannot be initialized by an initializer list:

Standard C++ allows this on structs and classes, except that these objects must conform to the Plain Old Data (POD) definition; non-POD classes cannot use initializer lists, nor can useful C++-style containers like std::vector and boost::array.

note from --Lightness1024 (talk) 21:50, 22 April 2009 (UTC) : I don't know where this quotation comes from, but the last part is false to my knowledge. In current C++ standard and boost implementation, array is an aggregate and can be initialized with init-list. notably, this form is correct

boost::array< int, 2 > a = {{1, 2}};  // initializes the elems[N] (only) member.
boost::array< int, 2 > a = {1, 2};  // acceptable too according to boost documentation. compiles with a warning on g++4.

end note.

For example:

std::vector<int> v = { 1, 2, 3, 4 };

I think that this is wrong. A non-pod can be initialized, but cannot be part of an initializer list, eg:

std::vector< std::vector<int> > v = { std::vector<int>({10, 11, 12}), std::vector<int>({13, 14, 15}) };

So the first would be correct in C++0x, the second code ill-formed. Should the paragraph be changed to make that clear?

213.196.194.249 (talk) 22:08, 4 May 2008 (UTC)

Technically, both the first and second would be valid C++0x (there's still some dispute with regard to uniform initialization). However, the paragraph wasn't talking about C++0x yet; references to "Standard C++" mean "C++03". Korval (talk) 05:38, 5 May 2008 (UTC)

Name conflict resolution on concept maps

My doubt is the concept version of inheriting from two classes which have a common member name.

Suppose I write a template with one type as parameter, and which requires that type to satisfy two concepts (hence using the generalized notation):

template<typename T> requires Concept1<T>, Concept2<T>
  void f(T x) {
    ...
  }

Now imagine both concepts consist, e.g., on having a typename defined:

concept Concept1<typename T>
{
  typename pointer;
  //...
}

concept Concept2<typename T>
{
  typename pointer;
  //...
}

And as none of the concepts is "auto", they must be satisfied by explicit concept_maps. Now both concept_maps may have to define different things for the typename "pointer":

concept_map Concept1<MyClass>
{
  typedef char* pointer ;
};

concept_map Concept2<MyClass>
{
  typedef int* pointer ;
};

If inside of my template function (f) I try to use T::pointer, and I have specialized T to MyClass, the compiler won't be able to resolve which one I want (either char* or int*). Is there a way to specify to which concept I refer when writing ::pointer? (IIRC, when faced with the analogous problem on inheriting from two classes, one could use the sintax base1::member and base2::member to distinguish between them.) -- User:Euyyn —Preceding unsigned comment added by 212.0.110.2 (talk) 18:23, 17 July 2008 (UTC)

That's an interesting issue. However, this is not a discussion forum for how C++0x will work in specific detail. Please see the PDF article on concepts for further details.
That being said, I'm guessing that it would be erronous to do what you say. That is, if concept mapping is to be used, each constraint on the template must resolve to the same concept map. Korval (talk) 02:20, 18 July 2008 (UTC)

Delete 5.6 Uniform Function Syntax

In private correspondence with an influential member of the standards committee I'm told that "the 'uniform function syntax' is not part of C++0x and IMO is unlikely to become one." 24.5.238.80 (talk) 21:11, 27 July 2008 (UTC) Jon Kalb

OnlyInt question and possible suggestion.

Hi, I read this part of the article:

struct OnlyInt
{
  void f(int i);
  template<class T> void f(T) = delete;
};

and that made me wonder if this would work:

template<class T>
struct OnlyInt
{
  void f(T) = delete;
  void f(int i);
};

OnlyInt<int> x;

x.f( 5 ); // Valid?

I guess the question is whether f(int) or f(T) will get called, and if f(T) is called, maybe that should be noted. I tried to test this, but void f(T) = delete wouldn't compile with GCC (as expected).

Thanks in advance. Posted by SoC (talk) -- Posted at: 20:31, 11 August 2008 (UTC)

This isn't valid, because the specialization OnlyInt<int> contains two identical function declarations. Note that in the example, OnlyInt is a class, not a template, and the deleted function is a member function template. In this case OnlyInt().f(5); is valid, and that's the entire point of the example (that a normal function is a better function than a function template specialization when there is no conversion involved). decltype 09:39, 2 February 2009 (UTC)

Removal of User-defined Literals Section

User-defined literals were last described in N2378 (8/1/2007) but were not included in the draft N2606 (5/19/08). They are also not listed on GCC's C++0x features to implement, which, while it shouldn't be taken as authoritative, is probably a good indication that its not considered a feature that's likely to go into the final standard. Since there is supposed to be a new working draft coming in October, if that draft should include user-defined literals, the section can be reinstated, but to me right now it looks like they've been turned down.

--98.232.203.240 (talk) 06:12, 26 August 2008 (UTC)

That logic is not sufficient to remove that section of the page. The GCC status update only includes functionality that has been voted into the working draft. Concepts are not on that list, despite the fact that WG21 is adamant about getting concepts in C++0x. Concepts are also not in the working paper, which will happen fairly soon. So just because something isn't in the working draft yet doesn't mean it shouldn't be presented on this page. The next meeting should tell us whether extensible literals make it or not, so keeping it around for a month won't hurt anyone. Korval (talk) 02:08, 27 August 2008 (UTC)
User-defined literals are currently in the working draft, N2798. It's section 13.5.8. --Snaxe/fow (talk) 16:18, 20 April 2009 (UTC)

Expected release date?

Is there any estimate of a release date? Are we looking at 2009 or 2010? Or later? Might be good to include if there's a source. 71.244.5.124 (talk) 23:02, 31 October 2008 (UTC)

As the standard is called C++0x, it was supposed to be released at most in 2009. 90.39.68.35 (talk) 07:40, 4 April 2009 (UTC)

better example for move semantics?

"For example, a std::vector is, internally, a wrapper around a C-style array with a size. If a vector temporary is created or returned from a function, it can only be stored by creating a new vector and having it copy all of the R-value's data into it. Then the temporary is destroyed, deleting its data."

This example is just stupid, because copy-on-write makes the trick right now in old C++. I don't see the point of the move stuff from it... 192.100.124.218 (talk) 14:20, 16 March 2009 (UTC)

COW will work until you start changing the vector. Consider a function append that takes a vector, appends an element to it and returns the new vector. In COW, it will copy the whole vector every time you execute push_back, even if the original vector is temporary and you don't care about preserving its contents. With rvalue reference, no copy will be done if a temporary is passed, so you can write like this: append(append(append(std::vector<int>(),1),2),3); and there will be no copies made. Try to achieve this with COW. Enerjazzer (talk) 00:40, 12 June 2009 (UTC)
I was under the impression that a copy-on-write implementation of std::vector would be near-impossible to make. Consider the fact that a user can obtain a pointer to an element of the vector at any time using either &v[n] or &*iter. This pointer must remain valid until a reallocation or an insert in front of the pointee takes place. The same applies to iterators and references. I don't see how an efficient COW implementation can preserve these semantics. Perhaps you were referring to return value optimization, which will probably eliminate the copy in the quoted example decltype (talk) 15:24, 16 March 2009 (UTC)
I dont see your point. COW is about copy data only if necessary. Pointers and iterators will stay valid for the current container, even if another one (which refers to the same array) makes some writing: cow will cause that it will be than reallocated and copied, but the pointers and iterators will point to the original. In assigments what you change is only a pointer, returning from a function is an assigment (if there is anyone who wants to use the return value).

192.100.124.218 (talk) 09:53, 17 March 2009 (UTC)

Consider the following example:
#include <vector>
using std::vector;
int main()
{
  vector<int> v1(1000); // holds 1000 ints 
  const vector<int> v2 = v1; // uses COW - no deep copy made...
  
  const int * p = &v2[42]; // ...but the vector *must* be copied here, 
                           // even if no "writing" takes place....
                        
  vector<int>().swap(v1); // Otherwise, the pointer p is invalidated here                      
}
decltype (talk) 10:11, 17 March 2009 (UTC)

In this case, const int& operator[] will be called, so the compiler can assume you wont do any writings. If you get the adress of a const&, its up to you if you want to write on it, so no copy will needed. Im not even sure you can get the address of a const with a non-const-pointed pointer. But this is considered hacking in my terms... 192.100.124.218 (talk) 12:51, 17 March 2009 (UTC)

No, a copy has to be made even after a call to a operator[] const. Even something like int i = *p; would have undefined behaviour if no copy was made. decltype (talk) 13:06, 17 March 2009 (UTC)
Otherway, i dont understand you. If you swap the v1 with an empty vector, what does that to make with p? v2 will hold the area, and the unnamed vector too, till the end of the scope. p is not invalidated... 192.100.124.218 (talk) 08:30, 20 March 2009 (UTC)
No, the unnamed temporary is destroyed at the end of the full-expression, not the enclosing scope. The following example demonstrates the same, but is less subtle:
#include <vector>
using std::vector;
int main()
{
  vector<int> v1(1000); // holds 1000 ints 
  const vector<int> v2 = v1; // uses COW - no deep copy made...
  
  const int * p = &v2[42]; // p actually points into v1, since they share the buffer
             
  v1 = vector<int>(); // frees the memory held by v1. p is invalidated
  
  int i = *p; // dereferencing invalid pointer!              
}

decltype (talk) 08:40, 20 March 2009 (UTC)

No, the line v1 = vector<int>(); wont free the memory used by v1, because v2 still points to it. v1 knows that someone else points to its buffer, so wont free it. 192.100.124.218 (talk) 12:05, 20 March 2009 (UTC)
Try this example:
                vector<int> v1(1000), v2 = v1;
                const vector<int> &cv1 = v1, &cv2 = v2;
                const int *p = &cv1[42], *q = &cv2[42];
                v1[42] = 17;
                if (*p == *q) {
                    // error
                } else {
                    // ok
                }
Can a COW implementation deal with that? -- BenRG (talk) 12:25, 20 March 2009 (UTC)
Well, if it makes a copy even for operator[] const it should...but that wouldn't be copy-on-WRITE. Which is what I was trying to prove, but failed :) decltype (talk) 14:38, 20 March 2009 (UTC)
I dont see the point in the example. Lets see what happens. v1, v2 points to the same area on the first line. You give other, const names for v1 and v2, doesnt really matters. You point to the common area with 2 vectors. After that, you change a vector what should be considered const. Do you see my problem with that? C++ is not so hard to hacked, its in the language to give you opportunities. You can always write a const variable with some extra effort, but than the responsibility is on you. Here the v1[42] call is not the const one (obviously), so there will be copy made. Obviously. Iterators/pointers invalidated. Obviously. What did you proved here? Maybe you are right, but i really dont see :( 192.100.124.218 (talk) 15:22, 20 March 2009 (UTC)
Non-const std::vector<T>::operator[] can't make a copy because it's not allowed to invalidate pointers into the vector. (To put it another way, my example doesn't invoke any undefined behavior.) Non-const std::string::operator[] does invalidate pointers into the string; they made that provision specifically to allow copy-on-write implementations of std::string. But there's no such provision for vectors.
(Even if vectors had been defined differently, the copy-on-write approach would reduce the cost of vector moves but increase the cost of every non-const vector operation. Move semantics reduces the cost of vector moves without any downside.) -- BenRG (talk) 19:34, 20 March 2009 (UTC)
They at least considered removing the possibility for cow strings for concurrency reasons, N2668[[1]] - and as such I would suspect cow vectors would fare no better. I do not know how to find out if this was accepted or trashed, though. --84.209.14.149 (talk) 14:56, 26 March 2009 (UTC)
Look, it doesn't matter if a COW implementation of std::vector would be the effective equivalent of what you get with std::move. The fact is that std::move is useful for far more than just the std::vector example. std::auto_ptr, for example, benefits greatly from it, as do similar RAII structures. Even std::shared_ptr passing will be faster, since you don't have to bump a reference count and then decrease it again after the temporary is destroyed. The std::vector example is an easily understood one, which is why I choose it, but it is hardly the definitive value of std::move. The solution to the forwarding problem alone is justification enough for it. Korval (talk) 18:38, 20 March 2009 (UTC)
I agree. It's a good example, and one of the most oft-cited. Still, in the trivial case, RVO would take precedence and eliminate the copy/move. I also very much like the fact that you can store movable objects like streams in a vector, because of RR. It's a very visible change that you don't have to understand RR at all to benefit from. Of course, for full benefit you'd have to know how to make your own objects movable. decltype (talk) 20:09, 20 March 2009 (UTC)