error: invalid conversion from 'char**' to 'const char**' [duplicate] - c++

I've got a function that requires const some_type** as an argument (some_type is a struct, and the function needs a pointer to an array of this type). I declared a local variable of type some_type*, and initialized it. Then I call the function as f(&some_array), and the compiler (gcc) says:
error: invalid conversion from ‘some_type**’ to ‘const some_type**’
What's the problem here? Why can't I convert a variable to const?

See: Why can't I pass a char ** to a function which expects a const char **? from the comp.lang.c FAQ.

You have a few options to get around what jamesdlin outlined in his answer.
You could use an intermediate variable.
some_type const* const_some_array = some_array;
f(&const_some_array);
You could change the parameters of f.
void f(some_type const* const* some_array);

You probably need to specify some more context, for instance is the argument passed data into or out of (or both?) the function?
Try making your variable const as well:
some_type const *some_array = ....;
This reads as "some_array is a pointer to a const some_type". The code can't modify the thing being pointed at. So you have to declare your variable const before passing it to the function.
(Edited...)

Related

How can I use this pointer with pointer to member function

I have typedef for a function pointer:
typedef bool(WlanApiWrapper::* (connect_func) )(WLAN_AVAILABLE_NETWORK, const char *, const char *);
and have a method that returns a pointer to function:
const auto connect_method = map_algorithm_to_method(*network)
So I want to call that like that:
(*this.*connect_method)(*network, ssid, pass);
but gets error:
Error (active) E0315 the object has type qualifiers that are not compatible with the member function CppWlanHack C:\Projects\CppWlanHack\CppWlanHack\WlanApiWrapper.cpp 52
but when I call that like that:
WlanApiWrapper f;
(f.*connect_method)(*network, ssid, pass);
all is building...
How can I call the method without creating an object, because I've already had an object (this pointer)
The error message sounds to me like you're calling a non-const member function pointer inside a const member function. this is a const WlanApiWrapper * inside a const member function so the object (*this) has type qualifiers (const) that are not compatible with the (non-const) member function.
To solve this, you can either make the connect_method const or make the member function that contains (this->*connect_method)(*network, ssid, pass); non-const.
Call it like this:
((*this).*connect_method)(*network, ssid, pass);
This should work with all compilers.
For more info, read How can I avoid syntax errors when calling a member function using a pointer-to-member-function? in C++ FAQ

invalid use of non-static member function in qsort C++

here is my function in class SuffixArray:
int pstrcmp(const void *a, const void *b) {
return strcmp((const char *)*(char **)a, (const char *)*(char **)b);
}
I used this comparison function in qsort:
qsort(ap, len1+len2, sizeof(char *),pstrcmp);
which ap is a pointer array of suffix
When I compile it, there is an error:
invalid use of non-static member function
and I use notepad++ to compile it, it provide that
error: cannot convert 'SuffixArray::pstrcmp' from type 'int (SuffixArray::)(const void*, const void*)' to type 'int (*)(const void*, const void*)'
qsort(ap, len1+len2, sizeof(char *),pstrcmp);
is there anyone can help me?
In C++ you need to pass a free-standing function or a static member function (as opposed to a non-static member function) to qsort, because calling conventions of non-static member functions require an instance to be passed.
You have two solutions to this problem:
Move the declaration of pstrcmp out of the SuffixArray class, or
Declare pstrcmp static in the class.

Invalid conversion from const &parameter to &parameter seems to be nonsense?

I am just curious. I am passing pointer to function with signature
void printCommandReceived(const CommandDescriptor &descriptor)
as third parameter to constructor with signature
CommandLogFilter::CommandLogFilter(QSharedPointer<LogServer> logServer, QObject *parent,
void (*preprocessValidCommand)(CommandDescriptor &descriptor))
and getting error from g++ compiler:
error: invalid conversion from ‘void (*)(const CommandDescriptor&)’ to ‘void (*)(CommandDescriptor&)’ [-fpermissive]
In my understanding the reference to non-const object should be usable as argument to reference to const object parameter. So parameter with type pointer to function accepting non-const object reference should be more than satisfied with (and do implicit conversion from) argument of type pointer to function, which accepts even const object reference.
Where am I wrong?
void (*)(const CommandDescriptor&) and void (*)(CommandDescriptor&) are two completely different, unrelated types.
There are very simple rules regarding const: X* can be converted to X const*, X** can be converted to X const * const * and so on. Same thing with references. Nothing else is allowed.
Note that the rules do not allow to arbitrarily add or remove const at any position in the type, for example, X** cannot be converted to X const **. This is true also for the position of function arguments: you just cannot add or remove const there to get a compatible type.
Could these rules be extended so that they accommodate cases like yours and remain consistent? Probably so. But they are not.
C++ has a limited set of situations where const can be added or removed implicitly. You ran into one where it cannot be done. The reason why not is probably as simple as "describing those cases which are safe would be hard, and standards writers are lazy and conservative".
As a work around, you can do this:
CommandLogFilter bob(
logServer,
parent,
[](CommandDescriptor &descriptor) {
return printCommandReceived(descriptor);
}
);
as stateless lambdas can implicitly convert-to a pointer to a function matching their signature.
I don't like having to make the signature explicit there, but there is no way to do something similar with template "auto" lambdas and have the signature deduced unfortunately.

Passing private static array as an argument to public member function in c++?

Online documents seem to suggest that a private member variable of a class that is passed as an argument to a public function in the same class needs to be declared as static. Still, I get a compilation error:
class C{
private:
static std::string table1[50];
public:
bool try (){
helper(&table1);
return true;
}
bool helper (std::string * table){
return true;
}
But I am getting this compilation error:
./c:72:31: error: cannot initialize a parameter of type 'std::string *' (aka
'basic_string<char, char_traits<char>, allocator<char> > *') with an rvalue of type
'std::string (*)[50]'
Is there something else that I missed?
Your helper function takes as a parameter a pointer to std::string. You are passing to it a pointer to an array of 50 std::string. Instead, pass the first element of the array (in this case the array decays to a pointer), like
helper(table1);
or
helper(&table1[0]);
I have serious doubts though that that's what you need. Pointers to std::string look a bit fishy here. Better use a std::vector<std::string>, or std::array<std::string, 50>.
Side note: don't call your member function try(), as try is a reserved C++ keyword.

Why is an array argument treated as a const array?

I am working with a member function that just sets the object's internal orientation to the values given in the argument:
void A::SetOrientation(float a[3]);
In another class, I have the following:
class B
{
public:
RestoreStateTo(A* const o_pA) const
private:
float d_orientation[3];
};
void
B::RestoreStateTo(A* const o_pA) const
{
o_pA->SetOrientation(d_orientation);
}
I get the following compiler error (with Visual Studio 2010):
error C2664: 'void A::SetOrientation(float [])' : cannot convert parameter 1 from 'const float [3]' to 'float []'
I found that I can avoid the issue with o_pA->SetOrientation(const_cast<float *>(d_orientation));, but I'd like to get a better grasp of what is going on.
I would appreciate an explanation as to why the array argument is converted to a const array as well as suggest the right approach to dealing with the error?
Because the prototype of your function void B::RestoreStateTo(A* const o_pA) const says you will not modify any member of B.
Since d_orientation is an attribute of B, it is const in this function.
Your SetOrientation function should take in a const,
void A::SetOrientation(const float a[3]);
Otherwise, it's possible that A::SetOrientation will modify the array you pass in. Because you have "B::RestoreStateTo(A* const o_pA) const", it means that the compiler won't let you pass a pointer to B::d_orientation as a non-const input, because A::SetOrientation has no guarantee not to modify it.
You have declared a const member function, and therefore all the members of this will be treated as const inside that function. So it shouldn't be surprising that d_orientation is treated as const.
It's the same principle that makes this code illegal:
const B* p = ...;
p->d_orientation[0] = 0.0f; // error, assigning member of `const` object