For my application I had to derive QtCoreApplication and use QCommandLineParser. I declared QCommandLineOptions instances in a separate namespace and wanted to declare the parser in this namepsace as well. However I get an error that I don't quite understand.
namespace
{
QCommandLineParser parser;
const QCommandLineOption optA("optA", "defaultOptA");
parser.addOption(optA); <-- error: unknown type name 'parser'
}
MyApp::MyApp(int argc, char *argv[])
:QCoreApplication(argc, argv)
{
setApplicationName("My App");
}
I have also tried declaring a QList<QCommandLineOption> so that I can add the options to it and add it the parser in on go using QCommandLineParser::addOptions, but that does not work either.
namespace
{
QList<QCommandLineOption> options;
const QCommandLineOption optA("optA", "defaultOptA");
options << optA; <-- error: unknown type name 'options'
}
MyApp::MyApp(int argc, char *argv[])
:QCoreApplication(argc, argv)
{
setApplicationName("MyApp);
}
What am I doing wrong in both cases ?
You can't have expressions like parser.addOption(optA) or options << optA in a namespace declaration. This is just C++ thing and has nothing to do with Qt. I would suggest you rather put the parser and optA variables in your MyApp class and initialize them in the MyApp constructor
class MyApp : public QCoreApplication
{
...
private:
QCommandLineParser parser;
const QCommandLineOption optA;
};
MyApp::MyApp(int argc, char *argv[])
: QCoreApplication(argc, argv), optA("optA", "defaultOptA")
{
parser.addOption(optA);
...
}
Related
I have a class which takes the main command line arguments (eg, -B, -a, etc) and does something with them, but also i would like to be able to instantiate that function without passing the command line arguments, so for example:
constructor:
myClass(int argc, const char **argv){
<initialise class with flags from argv>
}
myClass() : myClass(2, "-B") {}
}
Here i am trying to instantiate myClass with the flag "-B", but it keeps giving me the error:
no known conversion for argument 3 from ‘const char [3]’ to ‘const char**’
so i was wondering what i need to do to pass a value in as const char**?
First level is pointer to first pointer to char *. Second level is pointer to the first const char of c-string.
> cdecl explain "const char ** args"
declare args as pointer to pointer to const char
If you have -std=c++11 available, you can use this example (but it can be rewritten to use old standard):
#include <iostream>
#include <vector>
#include <string>
class test {
public:
test(const std::vector<std::string> & args) {
for (auto & arg : args) {
std::cout << arg << "\n";
}
}
test() : test{{"-B"}} {}
};
int main(int argc, const char ** argv) {
test sth{{argv+1, argc+argv}}; // skip program name here
test sth_else;
}
const char** is pointer to const char*. In your case, you intend to pass multiple arguments as part of argv, so you can pass something like below:
const char* argv[] = {"<program name>", "B"};
myClass m(2, argv);
Note: const char** x & const char* x[] are same. The 2nd syntax is helpful when one wants to "represent" an array.
Here I am giving a way to mimic the main(int, char**) function argument for your internal test. If you want to pass from default constructor to argument constructor then all the above stuff will have to go global.
I cannot understand why std::string converted into QString while passing it to constructor. Here is small example:
class StringHandler
{
private:
QString str;
public:
StringHandler(QString s): str(s) {}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::string str = "string";
QString qstr(str); // it gives error there are no constructor QString(std::string)
StringHandler handler(QString(str));//it does not give an error. Why?
return a.exec();
}
EDIT:
class StringHandler
{
public:
StringHandler(QString s): str(s) {}
QString str;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
std::string str = "string";
StringHandler handler(QString(str));//Here should be error, but there no error. Why?
qDebug()<<handler.str; //Error is here: request for member 'str' in 'handler', which is of non-class type 'StringHandler(QString)'
return a.exec();
}
Say hello to the most vexing parse.
StringHandler handler(QString(str)); declares a function named handler that takes a QString and returns a StringHandler. Yes. Thanks to the C++ parsing rules.
Now the error message request for member 'str' in 'handler', which is of non-class type 'StringHandler(QString)' makes sense: handler is being treated like a function of type StringHandler(QString) and you're trying to access a member named str in it, but of course functions have no members so the compilation fails.
You can fix this by using the uniform initialization syntax:
StringHandler handler{QString(str)};
The above can't be parsed as a function declaration, and so the compilation should fail for the expected reason: no matching constructor QString(std::string).
For more info, see C++'s most vexing parse again.
Here is my code:
// WorkDamnit.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
class Scheduler
{
public:
typedef void (*function_ptr) (void);
struct Task
{
function_ptr function;
int numOfTasks;
};
void Init(Task *tasks, int numOfTasks);
private:
int _numOfTasks;
Task *_tasks;
};
void Scheduler::Init(Scheduler::Task *tasks, int numOfTasks)
{
_tasks = tasks;
_numOfTasks = numOfTasks;
}
void count() {};
Scheduler::Task task_list =
{
count, 1
};
Scheduler scheduler;
Scheduler.Init(Scheduler::Task &task_list,1);
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
I get the following errors from the compiler:
1>c:\users\evan\documents\visual studio 2012\projects\workdamnit\workdamnit\workdamnit.cpp(49): error C2143: syntax error : missing ';' before '.'
1>c:\users\evan\documents\visual studio 2012\projects\workdamnit\workdamnit\workdamnit.cpp(49): error C2059: syntax error : '.'
The compiler doesnt seem to like the line after the class object definition. When i try to call the init() member. All i can think of is that it has to do with the pointer to function reference. Maybe someone can shed some light on this for me?
You can call call functions/methods directly outside of other methods/functions.
Scheduler.Init(Scheduler::Task &task_list,1);
2 problems in this line.
The above seems to be outside of any function/method. For eg. you can put in inside main.
The line itself is not correct. So change it to
scheduler.Init(&task_list,1);
Usually you call a method on an object not a class name, except for static methods. You don't pass the parameter type while passing parameters to the method.
So the changed line in main will look like
int _tmain(int argc, _TCHAR* argv[])
{
scheduler.Init(&task_list,1);
return 0;
}
Line 49 should be:
scheduler.Init(Scheduler::Task &task_list,1); // note the lowercase 's': the object should be used, not the class
Also it should be within a function (maybe main in your case)
Anyone knows how to compile this example code under msvc2010 ? (supposedly compiles under GCC)
class cmdLine;
struct cmdList
{
const char *c;
const char *s;
const char *h;
void (cmdLine::*cmdFuncPtr)();
};
class cmdLine
{
public:
cmdLine();
static cmdList myCmdList[];
void test();
};
cmdLine::cmdLine()
{
}
void cmdLine::test()
{
}
cmdList cmdLine::myCmdList[] =
{
{"xxx", "yyy", "zzzzz", &cmdLine::test},
{"aaa", "bbb", "ccc", 0}
};
int _tmain(int argc, _TCHAR* argv[])
{
cmdLine c;
(c.myCmdList[0].*cmdFuncPtr) (); //error (why?)
}
I get error C2065: 'cmdFuncPtr' : undeclared identifier and dont know whats wrong ?
Use this syntax
(c.*c.myCmdList[0].cmdFuncPtr) ();
As cmdFuncPtr is a pointer to a method of cmdLine, it needs an instance of the class to be invoked on, which is c. At the same time, cmdFuncPtr is a member of cmdList, so it needs an instance of the class where it is stored, which is c.myCmdList[0]. That's why c shall be used twice in the expression.
The expression presented by OP parses as: "Invoke a method on an instance of a class in c.myCmdList[0] through a method pointer stored in a standalone variable cmdFuncPtr". Such variable doesn't exist, that's what the compiler complains about.
Works:
static void WINAPI ServiceStart(DWORD argc, LPTSTR* argv);
int main() {
SERVICE_TABLE_ENTRY DispatchTable[] = {
{"MyService", ServiceStart},
{NULL, NULL}
};
}
Doesn't work:
error C2440: 'initializing' : cannot convert from 'void (__stdcall Service::* )(DWORD,LPTSTR *)' to 'LPSERVICE_MAIN_FUNCTIONA'
class Service {
static void WINAPI ServiceStart(DWORD argc, LPTSTR* argv);
};
int main() {
SERVICE_TABLE_ENTRY DispatchTable[] = {
{"MyService", Service::ServiceStart},
{NULL, NULL}
};
}
You must use & in that context to obtain a correct pointer.
Use &Service::ServiceStart, not Service::ServiceStart.
One piece of advice: since you made it a static function of Service class, rename it as well. ServiceStart is unnecessarily long. I think Service is implied here. If so, then make it just Start:
class Service
{
static void WINAPI Start(DWORD argc, LPTSTR *argv);
};
And then use &Service::Start.