On compiling following code I get error "expected unqualified-id before string constant"
In file "Notification_Constants.h"
namespace NOTIFICATION_CONSTANTS
{
#define SERVICE_EMAIL "service#company.com"
}
In file SendEmail.cpp
#include "Notification_Constants.h"
void UserPreferences::get_senders_email(String &_email)
{
_email = NOTIFICATION_CONSTANTS::SERVICE_EMAIL;
}
If i assign like following it works properly, what is the reason for the compilation error.
_email = SERVICE_EMAIL;
There is a similar question but the reason is not mentioned.
String class declaration with relevant methods
class String
{
public:
String();
String(const String& src);
String(const char *new_str);
String& operator=(const String& src);
String& operator=(const char *new_str);
};
First, you should put quotation marks around the email address:
#define SERVICE_EMAIL "service#company.com"
Second, you should not use #define at all. Use a const variable instead:
const String SERVICE_EMAIL = "service#company.com";
#defines are type unsafe, have no scope and are generally evil.
Last, you may want to consider using std::string instead of your String class.
Update:
The problem is that the preprocessor #defines are nothing more than text substitutions. When the preprocessor is done, your compiler will see
_email = NOTIFICATION_CONSTANTS::"service#company.com";
There is no string constant in that namespace. SERVICE_EMAIL is not an identifier of any kind - it is just an indication to the preprocessor to substitute any occurrence of SERVICE_EMAIL with "service#company.com".
The solution is to remove the namespace qualifier:
_email = SERVICE_EMAIL;
Better solution:
If you do not have access to the #define, you should wrap it in a header file, if possible:
#include "Notification_Constants.h"
namespace NOTIFICATION_CONSTANTS {
const String REAL_SERVICE_EMAIL = SERVICE_EMAIL;
}
and then use NOTIFICATION_CONSTANTS::REAL_SERVICE_EMAIL instead, which has scope, is a type, is a proper member of the namespace, and so on.
The problem is, I think since I don't know the String type, is that SERVICE_EMAIL should be a string literal:
#define SERVICE_EMAIL "service#company.com"
but then, it should fail even in the latter solution. Maybe your code snippet doesn't show the real problem.
#define SERVICE_EMAIL "service#company.com"
What's the type of service#company.com?
I think you wish to use a string to store an email address.
Try:
#define SERVICE_EMAIL "service#company.com"
Related
when I tried to compile the following code I got an error:
"include/IBCppClient/client/SoftDollarTier.h|3|error: variable
‘TWSAPIDLLEXP SoftDollarTier’ has initializer but incomplete type|".
I guess the code is correct since it is part of a stock broker's API. But I struggle to understand the part on class definition "class TWSAPIDLLEXP SoftDollarTier". As far as I know, this syntax is not legal in C++. What did I miss?
class TWSAPIDLLEXP SoftDollarTier{
std::string m_name, m_val, m_displayName;
public:
SoftDollarTier(const std::string& name = "", const std::string& val = "", const std::string& displayName = "");
std::string name() const;
std::string val() const;
std::string displayName() const;
};
C++ allows macro definitions, which allow the C preprocessor to essentially find-and-replace these macros with more elaborate definitions. A common practice in C/C++ is to insert function attributes before their names using preprocessor macros, and what likely happened is that your environment does not include the header file which defines TWSAPIDLLEXP, so the compiler interprets the string as the class name.
From a quick search, it seems that TWSAPIDLLEXP is defined in tws-api (not sure if this is the same broker) as:
#define TWSAPIDLLEXP __declspec(dllimport)
in IBJts/samples/Cpp/TestCppClient/StdAfx.h.
class A
{
public:
static bool S(int);
static string str;
static int integer;
};
bool A::S(int)
{
str+="A";
}
When I build the program, an error occurs: "str" undeclared identifier.
Ignoring for a second that the type is undefined, you will still get this error even if you use ints only.
The error you are seeing is because you are missing the definition of your static variable. You have declared it only.
string A::str = "initial value";
See: What is the difference between a definition and a declaration?
Probably you have more than one error, and the one you are centering your attention on is the least important:
ERROR line 5: string does not name a type
ERROR line 12: str undeclared.
The str is undefined because the type used to define it does not exist.
The solution would be to add
#include <string>
using namespace std;
at the beginning of the file (not that I recomment the using line anyway, but that's another story).
You should always center your attention into the very first error the compiler issues. But some popular IDEs out there are noteworthy for reordering them.
Sorry for this question but I am stuck.
I have folowing syntax:
class xx
{
..some simple fields like: int t; // )))
public: class anotherClass;
xx();
MyObj* obj();
string* name(); //error C2143: syntax error : missing ';' before '*'
}
i have write # include <string>
What does compiler wants from me?!
It wants you to tell him which string. You want the standard one:
class xx
{
public:
std::string* name();
};
Now, I'm not sure why you would be returning a pointer to a string. That's a segmentation fault waiting to happen, if you ask me. Two more viable options that seem reasonable to me:
class xx
{
std::string _name;
public:
const std::string& name() const
{
return _name; // WARNING: only valid as long as
// this instance of xx is valid
}
};
or
class xx
{
public:
std::string name() const { return "hello world"; }
};
You need to either fully qualify string or bring it into the current namespace:
std::string* name();
or
using std::string;
In a header, it's generally considered bad practice to pollute the global namespace, so the first is preferred.
The compiler does not know what string is because string is residing in the namespace std, not in the global namespace. You need to change string to std::string.
In your cpp file you can use "using namespace std;" or "using std::string;" and then just write "string". But you should never use using-namespace-declarations in header files.
BTW, as the others say returning a string* is unusal, normally you would return a string.
I am just trying to check whether compiler allows type name as variable name.
When i tried
int int;
It reported an error saying
error C2632: 'int' followed by 'int' is illegal
But when i tried
#include <string>
using namespace std;
int main()
{
string string;
}
It didn't give any error.
Both string and int are data types.
Why compiler allows string and doesn't allow int ?
EDIT: includes updated.
EDIT: Some people are saying that int is not a class.
In that case, why below line is allowed.
int a(10);
it works similar to constructor of a class.
string is not a C++ reserved word, but int is, and a reserved word cannot be used as an identifier.
And its syntactically fine to have class name and object name to be same.
class test {};
int main() {
test test; // test is an object of type test.
}
int is a C++ keyword. In the second declaration 'string string' declares an object of type 'std::string'. After this the name 'string' hides 'std::string' in an unqualified lookup
#include <string>
using std::string;
int main(){
string string;
string s; // Error
}
int is a keyword, whereas string is the name of a class in the standard library but is not a keyword.
string isn't actually a "data type" in the same sense the int is. int is a "native type" and as such, the text "int" is a keyword.
string is just a "user-defined" class (although, here the "user" the defined it is the C++ standards committtee). But as such, "string" is not a keyword.
So int int is two keywords together, but string string is just defining a varaible named "string" of type "string". The C++ compiler can keeps the separate two uses of "string" straight (but it's not a good idea to do this, since, as you've demonstrated, programmers often can't).
Well, given that others have essentially posted the answer, I'm going to go ahead and post what I meant...
I'm assuming that because the second answer compiles, that you have using namespace std; in your file (which is in general not a good idea; I fail to see why people tell beginning C++ users to do this).
When the compiler goes to resolve the first string, it is able to find the class in namespace std. The second use of string is simply the name of the variable.
The compiler allows primitive types to behave like classes for the purposes of templates - if you had to specialize for primitives everywhere it would be a nightmare.
Try removing
#include <string>
I have this header file, zeeheader.h, and I wrote some classes in it, I'm having problems giving a string as a parameter to one of the functions:
class DeliTest
{
public:
void DeliCheck(Stack*,string);
void ComCheck (unsigned,string);
bool EofCheck (unsigned,string);
};
As I was implementing it in the cpp file, I added #include to it, it seemed to be working, for example: as I was writing the "data." I got the "length()" appear by the intellisense, so I thought that it was working, but it wasn't. I got errors like:
syntax error : identifier 'string'
overloaded member function not found in 'DeliTest'
this is one of the functions in the cpp file:
bool DeliTest::EofCheck(unsigned i, string data)
{
if (i == data.length()-1)
return 1;
return 0;
}
Am I supposed to be adding something to the header file?
In the header file you need:
#include <string>
strings live in the std:; namespace, so your functions should look like:
void DeliCheck(Stack*, std::string);
and although it is not wrong to pass strings by value, as you are doing, it is more common and better practice to pass them by const reference:
void DeliCheck(Stack*, const std::string & );
Make sure to #include <string>, and because strings are in the std namespace, you should declare your strings as std::string in the header.
As a sidenote, make sure you do NOT declare using namespace std; in your header files. This would cause any other headers or c/cpp files that include this header to also use the std namespace. This is called polluting the namespace.
I assume you are trying to use the standard string class? If so you need to add:
#include <string>
at the top of your header file. And then also prefix your usage of string with std::; e.g.
void DeliCheck(Stack*, std::string);
You may also want to name your arguments for clarity, and you probably don't want to pass the strings by value:
void DeliCheck(Stack* s, const std::string& name);
You should #include <string> and keep in mind that string is part of the standard library so it is in the std namespace. You can either add: using namespace std; at the top of your header or fully qualify the string class with std::string where you use it. You really should get in the habit of using a fully qualified class name especially in a header file.