1

There is an answer on SO which explains how to perform a search for a value in an array. Coming from a PHP background, I am used to a degree of dynamic typization - something not present in C++, which then poses several challenges. Would it be then possible to create a helper function that would perform analogous to PHP's in_array($needle, $haystack) (for example, using the code from the linked answer) to be used as a shorthand?

Having written this snippet, I understand (tangibly) why it doesn't work - the parameters don't really have types signified. What, if anything, could be done to circumvent this, and would it be bad practice to do so?

bool in_array(needle, haystack) {
    // Check that type of needle matches type of array elements, then on check pass:
    pointer* = std::find(std::begin(haystack), std::end(haystack), needle);
    return pointer != std::end(haystack);
}

Edit: To be extra clear, I don't really want to PHPize C++ - what I was looking for is a way it's usually done in C++!

Ivan T.
  • 525
  • 5
  • 19
  • 2
    C++ is statically typed; You may want to use std::any to simulate PHP but the proper procedure is to get familiar with static types. – Michael Chourdakis Jun 18 '19 at 10:36
  • That's exactly what I'm trying to do, actually! Matter of fact, if there's a way to do this with static types, I would absolutely love that, because the only idea I have so far is just making an in_array function for each type I might need it for. – Ivan T. Jun 18 '19 at 10:38
  • 1
    In C++ we use templates to avoid rewriting a function for each type. – Michael Chourdakis Jun 18 '19 at 10:39
  • Trying to get one language to work like another is typically the first mistake, when learning a new one. C++ will not treat you well until you start leaning into its strengths. Forget about duck-typing, and start over. – sp2danny Jun 18 '19 at 10:43

2 Answers2

4

That's what templates are for:

template <class ValueType, class Container>
bool in_array(const ValueType& needle, const Container& haystack) {
// Check that type of needle matches type of array elements, then on check pass:
    return std::find(std::begin(haystack), std::end(haystack), needle) != std::end(haystack);
}

Provided that Container type is either a C-style array or it has accessible member methods begin() and end(); and that ValueType is convertible to Container::value_type, this should work.


This being said, templates are not an easy topic to handle. If you want to learn more, I recommend you one of good C++ books

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
  • There doesn't need to be an `std::begin` and `std::end` for `Container`. If it has `begin()` and `end()` member functions, which any sane container type will have, `std::begin` and `std::end` will work. – Nikos C. Jun 18 '19 at 10:48
  • @NikosC. Well, if the container has those member functions, then there is `std::begin` and `std::end` for the container. That's why they work. – eerorika Jun 18 '19 at 10:54
  • @eerorika That's not correct. If you define your own container type, there is no `std::begin` overload or specialization for it. But it will work fine if your custom container has a `begin()` member function. – Nikos C. Jun 18 '19 at 10:55
  • @NikosC. There is an overload for the container. The specific template overload that returns `c.begin()`. – eerorika Jun 18 '19 at 10:58
  • @Nicos Yes, I couldn't find the right wording to name it. C-style array has it's overloads, but for others it relies on existance of `begin()` and `end()` member methods. If you have better proposition, feel free to edit or suggest it in comments. – Yksisarvinen Jun 18 '19 at 10:58
1

Templates let you write the function

template <class T, class U, size_t N>
bool in_array(const T& needle, U (&haystack)[N]) {
    // Check that type of needle matches type of array elements, then on check pass:
    return std::find(std::begin(haystack), std::end(haystack), needle) != std::end(haystack);
}

But I'm not really sure what this gets you, it's still statically typed. Static typing is a good thing of course.

Untested code.

john
  • 85,011
  • 4
  • 57
  • 81
  • @sp2danny Yes, but that was the question I think. Obviously the OP should be using proper C++ instead of trying to make C++ like PHP, but I'm just answering the question. I expect they'll realise the benefits of C++ soon enough. – john Jun 18 '19 at 10:42