Is it possible to get the command line arguments without receiving
them via int main(int, char**)
?
Yes, with platform-specific functions. But that's not necessary (see below).
I don't want to pass the arguments to multiple methods,
That's understandable. It's an anti-pattern also known as "tramp data".
Also, I do not want to store the arguments by myself via global variables.
Yes, global variables are rarely a good idea.
Here's an alternative approach: store them as a static
local container object in some globally available non-member function which returns the container by reference.
Example:
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string>& Arguments()
{
static std::vector<std::string> arguments;
return arguments;
}
void f()
{
// use arguments anywhere else:
std::cout << Arguments()[0];
}
int main(int argc, char* argv[])
{
for (int i = 0; i < argc; ++i)
{
Arguments().push_back(argv[i]);
}
f();
}
Of course, this can be made more sophisticated. For example, you might want to prevent anyone else but main
from changing the vector by wrapping the vector in a class and declaring main
as a friend
, something like this:
#include <iostream>
#include <string>
#include <vector>
class Arguments final
{
public:
static int Count()
{
return arguments.size();
}
static std::string Get(int index)
{
return arguments[index];
};
private:
Arguments() = delete;
friend int main(int argc, char* argv[]);
static std::vector<std::string> arguments;
};
std::vector<std::string> Arguments::arguments;
void f()
{
// use Arguments anywhere else:
std::cout << Arguments::Get(0);
}
int main(int argc, char* argv[])
{
for (int i = 0; i < argc; ++i)
{
Arguments::arguments.push_back(argv[i]);
}
f();
}
Note that special care is needed to avoid bugs at program shutdown, when static objects are destroyed. You must make sure that no destructor of a static object accesses Arguments
, or else you risk undefined behaviour.