I’ve recently been porting a Python application to C++, but am now at a loss as to how I can port a specific function. Here’s the corresponding Python code:
def foo(a, b): # Where `a' is a list of strings, as is `b'
for x in a:
if not x in b:
return False
return True
I wish to have a similar function:
bool
foo (char* a[], char* b[])
{
// ...
}
What’s the easiest way to do this? I’ve tried working with the STL algorithms, but can’t seem to get them to work. For example, I currently have this (using the glib types):
gboolean
foo (gchar* a[], gchar* b[])
{
gboolean result;
std::sort (a, (a + (sizeof (a) / sizeof (*a))); // The second argument corresponds to the size of the array.
std::sort (b, (b + (sizeof (b) / sizeof (*b)));
result = std::includes (b, (b + (sizeof (b) / sizeof (*b))),
a, (a + (sizeof (a) / sizeof (*a))));
return result;
}
I’m more than willing to use features of C++11.
Your first problem is related to the way arrays are (not) handled in C++. Arrays live a kind of very fragile shadow existence where, if you as much as look at them in a funny way, they are converted into pointers. Your function doesn’t take two pointers-to-arrays as you expect. It takes two pointers to pointers.
In other words, you lose all information about the size of the arrays.
sizeof(a)doesn’t give you the size of the array. It gives you the size of a pointer to a pointer.So you have two options: the quick and dirty ad-hoc solution is to pass the array sizes explicitly:
Alternatively, and much nicer, you can use vectors instead of arrays:
Vectors are dynamically sized arrays, and as such, they know their size.
a.size()will give you the number of elements in a vector. But they also have two convenient member functions,begin()andend(), designed to work with the standard library algorithms.So, to sort a vector:
And likewise for
std::includes.Your second problem is that you don’t operate on strings, but on char pointers. In other words,
std::sortwill sort by pointer address, rather than by string contents.Again, you have two options:
If you insist on using char pointers instead of strings, you can specify a custom comparer for
std::sort(using a lambda because you mentioned you were ok with them in a comment)Likewise,
std::includestakes an optional fifth parameter used to compare elements. The same lambda could be used there.Alternatively, you simply use
std::stringinstead of your char pointers. Then the default comparer works:Simpler, cleaner and safer.