list< T >::iterator or syntax error? - c++

I'm currently getting the following compile errors:
In function 'int main()':
error: expected primary-expression before '>' token
error: missing template arguments before 'i'
error: expected ';' before 'i'
error: 'i' was not declared in this scope
I've highlighted the line the first error flags on in the code block below:
// test highscoresfilemanager reading & writing
/*
HighScorePair paira("holly", 10);
HighScorePair pairb("carl", 20);
*/
list< HighScorePair > list;
//list.push_back(paira); list.push_back(pairb);
HighScoresFileManager::GetInstance()->ReadFileToList(list);
list< HighScorePair >::iterator i; //ERROR FLAGS HERE ODDLY
for(i = list.begin(); i != list.end(); ++i)
std::cout << (*i).playerName << " " << (*i).playerScore << std::endl;
I left in some commented out text I was using to test something previously because I'm certain that that commented out text works perfectly and if it works I don't see why the new code I've added wouldn't work, I'm not using any new classes or anything, I've just tried to get an iterator setup.
I feel quite rude as I think I'm basically asking someone to check my syntax, I keep reading over it and thinking I must be missing a colon somewhere or something but I just can't see what the issue is! A new eye would be greatly appreciated! I appreciate you might want more code (which I can provide) but like I said if the stuff commented out worked then I think the new code should to.

Don't call your variable list.

First, I'm supposing that you've got a using namespace std; somewhere;
that's generally not a good idea. But the basic problem would remain
(albeit not for list, since you'd write `std::list): you've defined a
local variable with the same name as a symbol in a larger scope; the
local variable hides that symbol from its point of declaration until it
goes out of scope. So up until the line:
list< HighScorePair> list;
, list refers to the symbol you pulled into global scope with using
namespace std;, and after that line, until the end of the block, it
refers to the variable you have just defined here. The variable is
not a template, and its type doesn't support <, so list < isn't
legal.
As a general rule, I would recommend against hiding names. It leads to
confusion. Also: type names should be unqualified nouns (like list),
variable names should be qualified nouns (like currentList). At least
in principle; I can see cases where such a rule would be overkill.

Guess you wrote using namespace std; When you call variable that associate with function in std:: it will throw compile error. Just use exact namespace when define variables ( std::list ).

Related

error: cannot resolve overloaded function based on conversion to type ‘int’

I wrote the following code :
#include<bits/stdc++.h>
using namespace std;
int lengthOfLastWord(string A) {
int m= A.size();
int i=0;
while(i<m)
{
if(A[i]==' ')
{
int count=0;
i++;
while(A[i]!=' ')
{
count++;
i++;
}
}
else
i++;
}
return count;
}
int main()
{
string A;
getline(cin,A);
cout<<lengthOfLastWord(A);
}
But it is showing the following error
error: cannot resolve overloaded function ‘count’ based on conversion to type ‘int’
I am unable to understand why is it showing this error and what should I do to fix it.
Please help me.
Thankyou
Inside the if scope, your count variable is colliding with (technically "shadowing") std::count. However, your local count does not exist in the scope of your return statement, so the compiler is trying to use the only count that it knows about at that point, which is std::count.
This is a great example of why using namespace std and #include<bits/stdc++.h> are both bad ideas. If proper includes and namespaces were used, this code would have given you a much clearer compile error:
error: 'count' was not declared in this scope
The most direct reason is because your count variable is defined in the if scope, and not available in the scope of return statement.
However, the error you are seeing is confusing, since you have using namespace std in your code, and it makes completely unrelated (for your purposes) function std::count visible everywhere in your program, including your return statement. From the compiler perspective, you are trying to return a pointer to std::count, but since this function is overloaded template, compiler doesn't know which one you are trying to return - thus the phrasing of the errror.
If you remove the using namespace std from your code, which you should have never had in the first place, your code will still fail to compile, but error message would be way more easier to understand.
One solution is to rename your count variable to something else like total.
The compiler is considering std::count function instead of the count variable which is int.

Namespace information compromises the readability in C++

I'm new to C++ and had a background in C. The one thing which is quite difficult for me to adopt is to frequently use scope operator e.g. std:: Well, i'd avoid it usage by putting using namespace std at the start of my source code but a lot of people doesn't use this method as they think this may bite them in future.
Plus, the visual-studio also shows error/warning messages along scope operator e.g.
cannot convert from 'std::vector<int,std::allocator<_Ty>> *' to 'std::shared_ptr<std::vector<int,std::allocator<_Ty>>>'
Though the above message is verbose but its such a pain to read it (?). I think it can be simple to read if it was in this form
cannot convert from 'vector<int,allocator<_Ty>> *' to 'shared_ptr<vector<int,allocator<_Ty>>>'
1) Why everyone is using std::, even for cout, cin, endl ? Why would anyone use the labels for some other purpose anyways?
2) Is their a workaround in Visual studio to not show me error/messages/syntax-highlights with a prefix std:: ?
Although, as pointed out in the comments, code like using namespace std; is considered bad practice, you can avoid repeated use of the namespace prefix in code like std::cout, by specifying individual scoped elements in using statements.
Something like this:
using std::cout; //
using std::cin; // You can, from then on, just use 'cout', 'cin' and 'endl'
using std::endl; //
For very common elements, like those listed in the above code, you can put the relevant using lines in a header file - typically, your 'global' header that you use to build your precompiled header.
For starters there is a difference in name lookup for qualified and unqualified names.
Consider for example the following program.
#include <iostream>
class A
{
private:
int x = 10;
public:
operator int() const { return x; }
friend void f( const A & )
{
std::cout << "f( const A & )\n";
}
};
void f( int )
{
std::cout << "f( int )\n";
}
int main()
{
const A a;
f( a );
::f( a );
return 0;
}
The program output is
f( const A & )
f( int )
Secondly using using directives can result in name collisions or selecting a wrong function due to the overload resolution.
Apart of this the code can be less readable because the reader will not know for example whether endl is std::endl or a user defined function defined in some namespace that is included in the name lookup due to numerous using directives.
There are situations when you need to use an explicit or an implicit using directive.
For example if you want to use declarations from the namespace std::placeholders or when you want to declare an inline namespace. But the scope of these directive is usually very limited. Another example is using using declarations. But again try to make their scopes as small as possible.
Inside a limited scope, for example within a function, it's logical to use using namespace std or any other using.
Repeating namespace names is tedious when you can avoid it at no cost. I 've seen lots of code infested with std::, especially when it comes to the usage of std::forward, std::move, std::function, std::thread etc.
C++ keywords like using are there for a reason; Unconditionally saying that "using namespace std is bad" is erroneous.
To answer your 2), I believe the answer is "No, there's no way to change the way VS writes out error messages to strain out all the std::".
The good news is that these error messages used to be much worse. You'd get error messages for all N variations on a given template, and then have to parse out the tiny spec of signal from the ocean of noise. Not fun. Heaven help you if you were using nested templates like std::vector<std::vector<std::string> > >.
So while template error messages can still be a bit verbose, the information presented is actual information, not spam spam spam eggs and spam without the eggs.
Oh, and >> used to always parse as a stream operator, so you had to add spaces between the >s for a nested template. UP HILL, BOTH WAYS!!!

C++ unknown name type

I have a header file defining some parameters. I have defined some of the parameters as extern. My program works fine with other data types such as double and int, except when I try to add vector variables. The declaration in header file is
extern std::vector<double> my_vec;
In my main file, I am constructing the vector using this code:
std::vector<double> my_vec(3,0);
When I try to clear the vector using the clear method, the compiler is giving an error saying that unknown type. I am not even sure how to debug this. Can someone help?
P.S. I was originally trying to assign some values to this vector using:
my_vec[0] = 1;
but the compiler says that C++ requires a type specifier for all declarations. I googled this error, but I don't understand because I am specifying the type of my_vec.
Edit: example:
main.cpp
#include "params.h"
#include <vector>
std::vector<double> my_vec(3,0);
my_vec.clear();
// edit: my_vec[0] = 1; this also produces an error
int main(){
return 0;
}
params.h
#include <vector>
extern std::vector<double> my_vec;
Error message:
main.cpp:6:1: error: unknown type name 'my_vec'
my_vec.clear();
^
main.cpp:6:7: error: cannot use dot operator on a type
my_vec.clear();
^
2 errors generated.
You can't execute statements outside of a function - which is what you're trying to do with my_vec.clear();. It doesn't matter that clear() is a method of the vector class - invoking a method (as opposed to constructing a variable) is a statement, just like x = 1; . Those belong in functions.
You have to put your statement somewhere in your main(), e.g.:
int main(){
my_vec.clear();
return 0;
}
or make sure and construct my_vec the way you want it to look like, to begin with.
Also, more generally, you should avoid global variables if you don't really need them. And - you very rarely do. See:
Are global variables bad?
Edit: OP asks whether we can get around this restriction somehow. First - you really shouldn't (see what I just said). But it is possible: We can use a static block, which is implementable in C++, sort of.

Namespaces confusion

I am new to namespaces and was trying this from C++ Primer
#include<iostream>
namespace Jill
{
double bucket;
double fetch;
struct Hill{ };
}
double fetch;
int main()
{
using namespace Jill;
Hill Thrill;
double water = bucket;
//double fetch; //<<<<<<<<<<<<//
std::cin>> fetch;
std::cin>> ::fetch;
std::cin>> Jill::fetch;
std::cout<<"fetch is "<<fetch;
std::cout<<"::fetch is "<< ::fetch;
std::cout<<"Jill::fetch is "<< Jill::fetch;
}
int foom()
{
Jill::Hill top;
Jill::Hill crest;
}
When the line marked //<<<<<<<<<<<<// is not commented I get expected results. i.e. the
local variable hides the global and Jill::fetch. But when I comment it out, there are 2 fetch left . global fetch and Jill::fetch. And the compiler gives the error
namespaceTrial1.cpp:17:13: error: reference to ‘fetch’ is ambiguous
namespaceTrial1.cpp:9:8: error: candidates are: double fetch
namespaceTrial1.cpp:5:9: error: double Jill::fetch
namespaceTrial1.cpp:20:26: error: reference to ‘fetch’ is ambiguous
namespaceTrial1.cpp:9:8: error: candidates are: double fetch
namespaceTrial1.cpp:5:9: error: double Jill::fetch
My question is why does the compiler get confused this lead to ambiguity? Why does it not assume fetch as just Jill::fetch , since I have added using namespace Jill at the start of main()
If I use declarative using Jill::fetch; at the start of main, the issue gets solved. because using Jill::fetch makes it as if it has been declared at that location. So, its like there is a local fetch variable. [Am i correct?] Why does using declaration behave as if the variable was declared at that location and using directive doesnt?
When you declare a local variable shadowing a global/namespace variable, you explicitly tell the compiler about that. However, when you are using using the variables of the namespace doesn't actually end up in the local scope.
From the specification (section 7.3.4, point 3):
A using-directive does not add any members to the declarative region in which it appears.
Also (from same section, point 6):
If name lookup finds a declaration for a name in two different namespaces, and the declarations do not declare the same entity and do not declare functions, the use of the name is ill-formed.
The using directive modifies name lookup in a way that isn't exactly intuitive to most programmers. The standard says this in [namespace.udir]p2:
During unqualified name lookup (3.4.1), the names appear as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace.
This wording means that names from the namespace do not appear in the current scope, but in some outer scope. In your example the using directive is in the function which is in the global namespace, and the Jill is also in the global namespace, so the names from Jill appears as if they are in the global namespace. (As Joachim said, the names aren't actually introduced there, so they don't immediately conflict with existing names and you only get ambiguous lookups when you actually use them.)
This is a simple case and the compiler gives you an error, which is good. It can actually get more complicated than that.
namespace Outer {
namespace Mid1 { int i = 1; }
namespace Mid2 {
namespace Tricky {
int i = 2;
namespace Inner {
void f() {
using namespace Mid1;
std::cout << i;
}
}
}
}
}
This will output 2, not 1, even though you had the using directive right next to the line referring to i. But the nearest enclosing namespace that contains both Mid1 and the using directive is Outer, so Mid1::i acts as if it was declared in Outer. If you had an Outer::i it would be shadowed by Tricky::i, and Mid1::i fares no better.
An easy solution is to ban using directives and only use using declarations and namespace aliases. They're far more intuitive.
using namespace will not give priority to names it imports resulting in what you already observed.
Getting ambiguity error here is language design decision: it would be rather dangerous for such prioritization to exist. Imagine that the Jill namespace is a large one maintained by several developers probably from different organization. You have no or limited control to its contents and still changes to it might silently change the meaning of your program.
[basic.scope.declaration] says that a local variable hides the global, after it's declaration
int j = 24;
int main() {
int i = j, j;
j = 42;
}
the identifier j is declared twice as a name (and used twice). The declarative region of the first j includes the entire example. The potential scope of the first j begins immediately after that j and extends to the end of the program, but its (actual) scope excludes the text between the , and the }. The declarative region of the second declaration of j (the j immediately before the semicolon) includes all the text between { and }, but its potential scope excludes the declaration of i. The scope of the second declaration of j is the same as its potential scope.
This explains why there isn't an error when you declare a local variable.
When the local variable is not declared, then you have a name clash. The compiler can not decide which fetch to pick, and throws an error.

Why does using the same count variable name in nested FOR loops work?

Why does the following not give an error?
for (int i=0; i<10; ++i) // outer loop
{
for (int i=0; i<10;++i) // inner loop
{
//...do something
}
//...do something else
}
The way I understand it, variables in braces ({...}) are in scope only within these braces. But the inner loop is inside the braces of the outer loop. So as soon as I declare int i=0 for the inner loop, shouldn't I get an error about multiple definitions?
You are actually making a new variable with the same name as another variable. Since they are in different scopes this is allowed, and the variable in the inner scope "owns" the name. You will not be able to access the outer-scoped i inside the inner scope.
The for loop declaration itself is part of the scope of the for loop, so counts as part of the inner-scope in the case of the second i.
The C++ compiler accepts this as valid, as the scope of the second is only within the { } braces. If you implement the same in C, you will see an error like this:
$ gcc test.c
test.c: In function ‘main’:
test.c:10: error: ‘for’ loop initial declaration used outside C99 mode
test.c:12: error: ‘for’ loop initial declaration used outside C99 mode
This is illegal in most C dialects; it is a legal C++ declaration, and so may be accepted if you are compiling C with a C++ compiler:
for( int i=0; i<5; ++i){}
It is common to have a loop iterator only in the scope of the loop in C++, but C makes sure (specially with the C90, not C99), that the declaration is outside the scope of the loop. Hope that helps ... :-)
So, when you declare another FOR loop within the older one, then the scope start fresh and your code compiles without any error in C++ or C99. This is the usual accepted norm for a scope declaration.
The best way to understand this is to think about everything between the ( and ) when you declare a for loop as being inside the braces of that for loop, at least as it relates to the scope.
To understand this, consider a function in which you have no x variable declared, then the following code inside will give you an error. (We are also assuming that you have no other x variable defined globally.)
for (int x = 0; x < 10; x++)
{
something();
}
x++; // error, x is not defined.
The inner loop starts another level of scoping, for loops start the scope in the loop definition so the second i is in a new scope.
see
http://en.wikibooks.org/wiki/C%2B%2B_Programming/Scope#Scope_using_other_control_structures
ARE YOU SURE YOU DON'T GET AN ERROR WHILE EXECUTING THIS ....?
you are trying to define the two int variable within the same boundary .due to this this will generate the error . in c# if u try out the same code you will get the error
Error 1 A local variable named 'i' cannot be declared in this scope because it would give a different meaning to 'i', which is already used in a 'parent or current' scope to denote something else