Error: Invalid conversion from 'char**' to 'const char**'
Similar questions did not appear to have the same set of circumstances (i.e. two functions with different const requirements on the same structure). Please only mark this as a duplicate if it genuinely is.
ROS/C++: http://wiki.ros.org/ROS/Tutorials
Argument Parser: https://github.com/jamolnng/argparse
I need to pass argv
to a function from ROS and a function from the argparse
header. The former takes a char**
the latter takes a const *char[]
.
Code example (basic patterns are just taken from the examples for both libraries):
int main(int argc, char **argv){
argparse::ArgumentParser parser("Parser");
parser.add_argument()
.names({"-v", "--video"})
.description("Enable video output for this node.")
.required(false);
parser.enable_help();
//Problem 1: requires argv to be "const *char[]"
auto err = parser.parse(argc, argv);
if (err){ /*error handling*/}
//Problem 2: requires argv to be non-const
ros::init(argc, argv, "node_name");
...
return 0;
}
I need to call both of these functions but they both require different types for the same structure. Function prototypes for clarity:
//Declaration 1
Result parse(int argc, const char *argv[]);
//Declaration 2
void ros::init (int & argc,
char **argv,
const std::string &name,
uint32_t options = 0
);
Is there a way I can call both functions?
Why is this even a problem? So far as I understand the
const
in Declaration 1 is just a promise that the functionparse()
will not modify theargv
; why does this need the variable to beconst
in the calling scope (https://isocpp.org/wiki/faq/const-correctness).
Edit - further information: On a hunch I tested a minimum working example without reference to either ROS or the argparsing libarary. Here is the test code:
#include <iostream>
void f(const char **a){
std::cout << a[1] << std::endl;
}
int main(int argc, char **argv){
// Attempt 1
f(argv); //Causes compilation error.
// Attempt 2
f(const_cast<const char**>(argv)); //No compilation error and correct functionality
return 0;
}
I further checked that the const_cast
resulted in the behaviour I desired (constness for the duration of the call to f()
and no more). Adapting Attempt 2 to the original problem solved my problem and I will add an answer below.
I am okay with the const_cast
here because I am elevating to const
and not trying to work around a data-structure which shouldn't be modified. That said I don't like const_cast
and I don't understand why it appears to be necessary in this case. I will leave the question open to see if anyone is willing to explain this (answer question 2 above), I'll post my functional solution.