4

In a scenario where a custom find() method of a custom class returns index position of an element in a custom data structure, is there something more elegant than returning string::npos?

The return type of the find() method is size_t. So I need it to be of type size_t.

string::npos is -1, which is the maximum value of unsigned long long. While this works great, my issue with it is the naming: string. I'd prefer not to have any association to string. Is there anything built in more generally named for such a common and general scenario and compatible with size_t?

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
code
  • 1,056
  • 10
  • 22
  • 2
    Why are you asking? Where are you using this? What do you mean by "associtation to string"? – Dai Mar 11 '18 at 02:28
  • Vectors and sets return `vec.end()` and `set.end()`, respectively, when `find()` fails... – Sumner Evans Mar 11 '18 at 02:28
  • I'm not sure I get your question. You could use `std::find`, but if you're searching `string` you might as well use `string` methods. – user4581301 Mar 11 '18 at 02:34
  • I'm not talking about vector or string. I have a custom class with a custom data structure. I just want to return index position of an element. In case not found I need to return something. While string::npos works fine...I don't like that it is packaged in the string class...which has nothing to do with my class. – code Mar 11 '18 at 02:39
  • 3
    Then define a `yourclass::npos`. (which is likely to equal to `(size_t)-1` as well) – user202729 Mar 11 '18 at 02:39
  • 2
    You could always return an `optional`. – chris Mar 11 '18 at 02:40
  • I would avoid indexes and use iterators if at all possible. – Galik Mar 11 '18 at 02:45
  • Why is that Galik? – code Mar 11 '18 at 02:53
  • @Galik "indices"? – user202729 Mar 11 '18 at 02:59
  • @user202729 both versions are good :) – Galik Mar 11 '18 at 03:02
  • @code Iterators are generally safer. Most algorithms expect iterators. And the iterator equivalent of `npos` is `std::end(v)` which is *one past the end* and that just happens to work out better when using it in further processes. The problem with `npos` is you often have to convert it to something useful before you can use it in a subsequent algorithm (like size()). – Galik Mar 11 '18 at 03:06
  • If you do use iterators, the two competing method for returning the current index based on an iterator would be [How to get index from iterator](https://stackoverflow.com/questions/2152986/what-is-the-most-effective-way-to-get-the-index-of-an-iterator-of-an-stdvector) which would apply equally to *string* using `std::string::iterator`. – David C. Rankin Mar 11 '18 at 03:06
  • Great points everyone. I see what you mean Galik. – code Mar 11 '18 at 03:09
  • If you want something "more elegant", you may have to explain the ways in which you think _npos_ is inelegant. – Lightness Races in Orbit Mar 11 '18 at 14:38

1 Answers1

0

If your custom class wants to return a size_t from it's find function, then just define your own size_t constant for consumers to reference as being "not found". For example (pseudo-code, not verified to compile):

class Foo
{
    public:
        static const size_t npos = static_cast<size_t>(-1);

        size_t find(/*thing to find here*/) const
        {
            // logic to search for element

            // element not found
            return(npos);
        }
};

and then consumer can use it similarly to std::string:

Foo foo;
size_t pos = foo.find(/*thing to find here*/);
if(pos != Foo::npos)
{
    // Element found
}
codesniffer
  • 1,033
  • 9
  • 22
  • Why did u static_cast? static_cast(-1); – code Mar 11 '18 at 16:08
  • @code Not sure which aspect you're asking about, but...IIRC some compilers will warn if trying to assign a negative number to an unsigned type, especially at the higher (more critical/pedantic) warning levels. And 'static_cast' definitely over C-style cast for its benefits. – codesniffer Mar 18 '18 at 14:49