http://msdn.microsoft.com/en-us/library/dh1a0227(v=VS.80).aspx
Use google :-)
-Seetharam
You see, maybe if we started to say:
Use Bing
Or
Bing it!
then maybe Microsoft would change its tune about dropping the
microsoft.* newsgroups. :)
--
HLS
> Hello, I am struggling to learn the concept of template language
> and the usage of CArray. I have found the CArray declaration in
> the afxtempl.h file and I have managed to compile with no errors
> the apparent construction of
May I suggest you to just go with STL std::vector?
It is more powerful than CArray.
For example, CArray does copies in a "naive" way using memcpy. This works
correctly only for PODs (Plain Ol' Data) but not for more complex classes.
Strange bugs may arise if you use CArray with non-POD classes.
(I recall some of these bugs were discussed in this newsgroup and on some
web forum.)
Moreover, you can easily compose std::vector with other containers (e.g. you
could simply build a vector<vector>).
And vector has a better dynamically-growth policy than CArray (not bad if
you store few items, but can make a difference for millions of items).
CArray uses arithmetic growth, which has a very bad O(N^2) asympotic
complexity; instead vector::push_back increases vector's capacity using a
1.5x factor, offering an amortized O(1) time.
> I am having a mental block with understanding the template
> declaration of
> template<class TYPE, class ARG_TYPE>
> What exactly is this saying ? The constructor is just CArray( );
Note that STL vector in its simplest form has only one template parameter,
i.e. the type you store in the vector, e.g.
vector<int> someIntegers;
vector<MyStruct> collectionOfMyStructs;
No need for the (useless and confusing, IMHO) ARG_TYPE thing.
Using vector is very easy:
#include <vector> // header file for std::vector
// Creates an empty vector storing instances of MyClass
std::vector<MyClass> data;
// Add some stuff
data.push_back( MyClass(...) );
data.push_back( MyClass(...) );
...
Use operator[] to retrieve vector elements (index is 0-based).
And you can use resize() to change vector size.
Other samples on using std::vector and description of its public methods can
be easily found using your favourite search engine.
HTH,
Giovanni
> For example, CArray does copies in a "naive" way using memcpy.
About the (improper) use of memcpy in CArray, it is clearly stated on MSDN
documentation:
CArray Class
http://msdn.microsoft.com/en-us/library/4h2f09ct.aspx
---[begin]---
Most methods that resize a CArray object or add elements to it use memcpy_s
to move elements. This is a problem because memcpy_s is not compatible with
any objects that require the constructor to be called. If the items in the
CArray are not compatible with memcpy_s, you must create a new CArray of the
appropriate size. You must then use CArray::Copy and CArray::SetAt to
populate the new array because those methods use an assignment operator
instead of memcpy_s.
---[end]---
Giovanni
Note that the declartion is not CArray(type) but CArray<type>,
Reading afxtempl.h is about the worst possible way to learn about this, because templates
are not trivial aspects of C++ to work with.
What do you WANT to do with it?
The most relevant operations are
SetSize
GetSize
Add
GetAt
SetAt
SetAtGrow
[]
joe
****
Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
#include <vector>
//...
size_t size = 10; //<-error C2258: illegal pure syntax, must be '= 0'
std::vector<int> array(size); //<- error C2252: 'size' : pure specifier can only be specified for functions
// also error C2061: syntax error : identifier 'size'
for(int i=0; i<size; ++i) //<-error C2059: syntax error : 'for'
{array[i] = i;}
// compiles with 180 errors but I think the rest are result from the above first 3.
---------Also this example will not compile
#include <vector>
//...
std::vector<int> v(2); //<- error C2059: syntax error : 'constant'
int& first = v.front(); //<-error C2327: 'CFileHandlingDoc::v' : member from enclosing class is not a type name, static, or
enumerator
//error C2065: 'v' : undeclared identifier
//error C2228: left of '.front' must have class/struct/union type
int& last = v.back(); //<-error C2252: 'last' : pure specifier can only be specified for functions
>However my compiler docs doesn't have much
> on this either, just linked refrences to the same declarations I am
> struggling to understand.
What compiler do you use?
I recall VC6 had some problems with STL implementation, but using STLport
(open source implementation of STL) fixed several of them.
(Since VC7.1 there were big improvements.)
> I did find one search page that does give some examples at
> http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4027
> but my compiler doesn't want to compile some of the code samples.
> So I am pretty much still stuck. Below are the examples that won't
> compile (from the above link) . When I cut these out of my text, it
> compiles with zero errors.
>
> #include <vector>
> //...
> size_t size = 10; //<-error C2258: illegal pure syntax,
> must be '= 0'
...it's like the compiler misinterprets 'size' like if it was a pure virtual
method?!
I believe you had some syntax errors.
Please post your entire C++ source code to have a better diagnosis.
Giovanni
> #include <vector>
> //...
> size_t size = 10; //<-error C2258: illegal pure syntax,
> must be '= 0'
> std::vector<int> array(size); //<- error C2252: 'size' : pure specifier
> can only be specified for functions
> // also error C2061: syntax
> error : identifier 'size'
> for(int i=0; i<size; ++i) //<-error C2059: syntax error : 'for'
> {array[i] = i;}
> // compiles with 180 errors but I think the rest are result from the above
> first 3.
This small test code compiles just fine with VC10:
<code>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
size_t size = 10;
vector<int> array(size);
for (size_t i = 0; i < size; i++) {
array[i] = i;
}
for (size_t j = 0; j < size; j++) {
cout << array[j] << endl;
}
return 0;
}
</code>
C:\TEMP>cl /EHsc /W4 test.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for
80x86
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
/out:test.exe
test.obj
C:\TEMP>test.exe
0
1
2
3
4
5
6
7
8
9
Giovanni
Yes I am using VC6 and unfortunately I like it but this appears to be yet another
reason to move on. I have two questions at this point.
1. Where can I get examples of this STLport ?
2. Can I install VS 2005 on the same machine without uninstalling my VC 6 ?
> 1. Where can I get examples of this STLport ?
But I believe that VC6's STL implementation is OK with basic std::vector
features.
I recall that I used std::vector in some VC6 projects without STLport, and
there seemed to be no bugs.
Some patches for VC6's STL implementation can be found here as well:
http://www.dinkumware.com/vc_fixes.html
> 2. Can I install VS 2005 on the same machine without uninstalling my VC 6
> ?
Yes.
You may also want to try VS2010 Express (free download).
Giovanni
> Thanks Giovanni you've been a great help.
You're welcome.
> These two links are better than any I found so far.
I'm glad you find them useful.
> I will decide which way I am going to fix this or just give
> up on this particular project and keep doing it long hand
> with a calculator. I cannot seem to get to base one before
> running into a block on this project.
Did you try the sample vector code snippet with VC6?
That code does not use fancy template metaprogramming techniques, so it
should compile and run fine on VC6, too...
(And if you experience some problems, you may try STLport or Dinkumware
patches.)
However, in the long-run, moving to a more modern version of the compiler is
a wise and good investement.
Giovanni
Yes I did and it had errors too, so was about to give it up.
I did not think there was anything wrong with my previous
code since the apps compiled with no errors and no warnings
before putting in the vector samples.
But out of desperation I created a totally new project and
made it the same base creation as the one I was having trouble
with. I put the
#include <vector>
#include <iostream>
using namespace std;
outside the ViewClass implementation but still in the cpp file just
like I had it in the other app but this time it compiled with no
errors. I don't understand why the previous app compiled ok
until I paste in the same code the same way and then it did not.
I may go back in and comment out everything I added and start
with the vector first and then add till I find it.
Just a couple notes:
> I put the
> #include <vector>
> #include <iostream>
I would suggest to put these #include's in "StdAfx.h" (precompiled headers).
> using namespace std;
In a real-world project, instead of 'using namespace std', I would just use
std::vector.
I think importing the whole std:: namespace is OK in simple test code, but
not in real-world apps.
HTH,
Giovanni
>In a real-world project, instead of 'using namespace std', I would just use std::vector. I think importing the whole std::
>namespace is OK in simple test code, but not in real-world apps.
Thanks and if you would comment further on these:
I have read that putting
using namespace std
in the include file "bloats" the application. But putting it in a cpp file
only affects that cpp file of the app.
What exactly does this mean. I have never really gotten under the
namespace thing but I thought it was something similar in concept
to a define.
Also I have always wondered when you include an include file,
it only adds "referenced" items to app from the includes, correct?
In other words it doesn't add the entire include code to your app,
correct ?
>
>
>>In a real-world project, instead of 'using namespace std', I would just use std::vector. I think importing the whole std::
>>namespace is OK in simple test code, but not in real-world apps.
>
>Thanks and if you would comment further on these:
>I have read that putting
>using namespace std
>in the include file "bloats" the application.
****
I fail to see how qualifying a namespace can "bloat" an application. I am not sure what
you read that suggests this, but a namespace is merely syntactic directive to the
compiler, and generates no code.
****
>But putting it in a cpp file
>only affects that cpp file of the app.
>What exactly does this mean.
***
As I said, I have no idea what this could possibly mean, since the notion of a syntactic
directive "bloating" an application seems inherently nonsensical.
****
>I have never really gotten under the
>namespace thing but I thought it was something similar in concept
>to a define.
****
No, it is a directive to C++ that tells it that when it has an unqualified name, it first
checks local scope, then class scope, then the selected namespaces, then the global
namespace. I'm not sure if there is a defined order to the namespace searches, or it is
left up to the compiler writer to determine the order, and I don't want to look it up
right now. But "bloat" is one of those nonsensical terms (like "crash") that seems to
have meaning but is largely nonsensical (for example: if you have code that is actually
callable, and does something, it is not "bloat", it is "part of the functionality of the
program". An unholy fascination with code size is the mark of a beginner ("What's wrong
with Windows? I did "hello world" and got <explanation of meaningless numbers follows>
but in Unix it is only <equally meaningless comparison of meaningless numbers>" as if .exe
file size, process address space size, or any other meaningless metric had relevance for
modern programming. But attributing "using namespace" to causing "bloat" sounds to me
like total nonsense.
****
>
>Also I have always wondered when you include an include file,
>it only adds "referenced" items to app from the includes, correct?
>In other words it doesn't add the entire include code to your app,
>correct ?
****
No, it substitutes the text of the included file, period. It is as if you had replaced
the #include with a copy-and-paste of the contents of the file. Nothing more, and nothing
less. If you have a header file that includes a million bytes of code, every compilation
gets a million bytes of code. But that would just be poor programming.
Note that the LINKER can drop subroutines that are not called, but this is not the role of
the compiler.
Note that 'using namespace' does NOT generate any code, so claiming it can "bloat" an
application is nonsense. And it does not make the runtime symbol table any larger,
because the runtime symbol table is going to be the same size whether you declare a 'using
namespace' or not. All the 'using namespace' declaration changes is the rules for how
that symbol table is searched!
Personally, I find 'using namespace std' to be an excuse for lazy programmers to not type
std:: ahead of what should be qualified names. I always type std:: in front of any
component of the std:: namespace; it is a better form of documentation, does not result in
ambiguities, and overall makes it more obvious to future maintainers what is going on. But
it cannot make your app bigger by using it.
joe
****
> ****
> I fail to see how qualifying a namespace can "bloat" an application. I am not sure what
> you read that suggests this, but a namespace is merely syntactic directive to the
> compiler, and generates no code.
> ****
>>But putting it in a cpp file
>>only affects that cpp file of the app.
>>What exactly does this mean.
> ***
> As I said, I have no idea what this could possibly mean, since the notion of a syntactic
> directive "bloating" an application seems inherently nonsensical.
> ****
Hey thanks for the reply! I got that at
http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4027/A-Beginners-Tutorial-For-stdvector-Part-1.htm
about one page or so down it says
"This is okay for small projects, as long as you write the using directive in your cpp file. Never write a using directive into a
header file! This would bloat the entire namespace std into each and every cpp file that includes that header. For larger projects,
it is better to explicitly qualify every name accordingly. I am not a fan of such shortcuts. In this article, I will qualify each
name accordingly. I will introduce some typedefs in the examples where appropriate-for better readability."
--
I saved the rest of your reply on namespace and includes to my notes folder.
Later........RB
>Hey thanks for the reply! I got that at
>http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4027/A-Beginners-Tutorial-For-stdvector-Part-1.htm
>about one page or so down it says
>"This is okay for small projects, as long as you write the using directive in your cpp file. Never write a using directive into a
>header file! This would bloat the entire namespace std into each and every cpp file that includes that header. For larger projects,
>it is better to explicitly qualify every name accordingly. I am not a fan of such shortcuts. In this article, I will qualify each
>name accordingly. I will introduce some typedefs in the examples where appropriate-for better readability."
The "bloating" they're talking about brings all the type, variable,
function, and other scoped names declared by the namespace into the scope
of the using-directive. This can lead to ambiguity and naming conflicts.
See the FAQ for more on why it's bad:
http://www.parashift.com/c++-faq-lite/coding-standards.html#faq-27.5
--
Doug Harrison
Visual C++ MVP
On Sun, 9 May 2010 20:19:26 -0400, "RB" <NoMail@NoSpam> wrote:
I have above the class implementation in my view class
#include <vector>
#include <iostream>
and then in the button handler implementation I have
size_t size = 10;
std::vector<int> array(size);
for (size_t i = 0; i < size; i++)
{
array[i] = i; // this goes ok with no error
}
for (size_t j = 0; j < size; j++)
{
cout << array[j] << endl; //error C2065: 'cout' : undeclared identifier
}
std::vector<int> v(2); // these last 3 also compile ok
int& first = v.front();
int& last = v.back();
//// I get the one error shown on the line above. But I can put back the
using namespace std; and also take out the prepended std:: of the two
vectors and it then compiles with no errors and no warnings.
> cout << array[j] << endl; //error C2065: 'cout' : undeclared identifier
The identifiers cout and endl are also in namespace std, so you need to
say:
std::cout << array[j] << std::endl;
Kind of a pain, but you could employ using-declarations to ease things:
using std::cout;
using std::endl;
This brings just these symbols into scope. That said, I don't know how
useful cout is in an MFC program...
Ohh... ok. Well you're right don't really need cout much it was just in the
sample code. I have been trying another sample for CMap which was
something I wanted to learn but my VC 6 compiler will not compile it.
Even though I have the #include <afxtempl.h> it will not acknowledge it.
The browser doesn't find CMap either with a BrowseGotoDefinition key
for whatever that's worth, not much as Joe would say.
CMap<CStrng, CString&, CPoint, CPoint&> MyMap2; //error C2065: 'CStrng' : undeclared identifier
MyMap1[CString (_T ("Vertex1"))] = CPoint ( 0, 0);
It may be the sample though because this will compile and browse
CMapStringToString MyMap2; // compiles ok
The first sample may be flawed, but it looked interesting since it will allow
a user defined type into CMap. I looked at structs in std::map but I am
so weak in template language that I will probably just have to pull off and
read some text for a few days. I have a legal bought copy of VC 2005 and
I am definitely going to install it this weekend. I dread getting acclimated
to a new environment since I had grown so used to the old VC 6.
Thanks for the help guy.
You should not mix MFC and non-MFC idioms in non-MFC programs. It is OK to use std:: in
an MFC program, but not to use MFC constructs in a non-MFC program. Note that if you are
generating a console app, you can check the "use MFC" option when you create the app, and
you will get all of the MFC library (which is overkill for a console app). Or you can
figure out which ATL header files need to be included to get the capabilities you need.
But the odd mix, that includes CString and cout, is more than a little weird.
joe
Did you see the error message
CStrng' : undeclared identifier
You have to type CString :)
> CMap<CStrng, CString&, CPoint, CPoint&> MyMap2; //error C2065: 'CStrng' :
> undeclared identifier
> MyMap1[CString (_T ("Vertex1"))] = CPoint ( 0, 0);
If you use std::map, you have to specify only two template arguments instead
of four: just the key type and the value type:
#include <map> // Use STL map container
std::map< CString, CPoint > MyMap;
MyMap[ _T("Vertex1") ] = CPoint(0, 0);
> I have a legal bought copy of VC 2005 and
> I am definitely going to install it this weekend.
Good move!
> I dread getting acclimated
> to a new environment since I had grown so used to the old VC 6.
You will miss VC6's ClassWizard and snappy IDE, but you will get several
good things, like a better C++ compiler, better libraries, and debugging
visualizers.
Giovanni
Joe I filed notes on your input.
If I wanted to buy one book on STL that was on a beginners
level but still offered excellent material. Do you know of such
a Title ?
>> CMap<CStrng, CString&, CPoint, CPoint&> MyMap2; //error C2065: 'CStrng' : undeclared identifier
> Did you see the error message CStrng' : undeclared identifier
> You have to type CString :)
Thanks I am slowly beginning to beginning to decphier logic of STL.
I did some more searching and found that for the above to work I
would have had to override the HashKey with a CString type.
Thanks Giovanni
Yes, I also remember you suggesting std::vector over CArray which I did want
to do buy the VC 6 help docs don't have much on std::stuff. Maybe VS2005
will. My biggest problem in this area is my incompetence in STL.
Recomend any one good book on it ?
> Yes, I also remember you suggesting std::vector over CArray which I did
> want
> to do buy the VC 6 help docs don't have much on std::stuff. Maybe VS2005
> will. My biggest problem in this area is my incompetence in STL.
I was incompetent in STL some time ago, and I believe that everyone was once
:)
I mean: everyone of us just learnt new things on the road.
As a starting point, I would suggest you to find some examples on the web
and tutorials and do some practice.
Just explore some methods of STL classes with simple console apps, to grasp
the general design and ideas in STL.
> Recomend any one good book on it ?
I think that this one is good:
http://www.amazon.com/Standard-Library-Tutorial-Reference/dp/0201379260
There will be some lessons on STL on Channel9 (http://channel9.msdn.com/)
soon.
Giovanni
I searched for it a few month ago because someone had asked a similar question, and
couldn't find it. But I remember it as being a useful book back when I was trying to use
STL. Part of the problem was that at the time I was using VS6 and VS.NET with its
numerous language fixes were not out yet.
joe
A "must have" book about the C++ standard library (which includes the
containers library, aka STL) is the following:
"The C++ Standard Library A Tutorial and Reference", Nicolai Josuttis,
Addison Wesley.
Regards
--
Cholo Lennon
Bs.As.
ARG
Ups, you're right
Does it also have
> code examples of the containers library ?
>
Yes, the book has usage examples for every container :-)