开发者

How does one generally get the end of a string in C++0x?

template<typename ForwardIterator, typename StringType>
inline bool starts_with(ForwardIterator begin, ForwardIterator end, const StringType& target)
{
    assert(begin < end);
    if (std::distanc开发者_如何学运维e(std::begin(target), std::end(target)) > std::distance(begin, end))
    {
        return false;
    }
    return std::equal(std::begin(target), std::end(target), begin);
}

This fails because std::end returns one past the '\0' if StringType is a string literal, not the '\0'. (In this respect, it's similar to the range based for loop inconsistency ) How does one work around this?


How about making a little trait class for your string template parameter:

template <typename TString>
struct StringBounds
{
  typedef typename TString::const_iterator citerator;
  static citerator Begin(const TString & s) const { return std::begin(s); }
  static citerator End  (const TString & s) const { return std::end(s); }
};

template <typename TChar, size_t N>
struct StringBounds<TChar[N]>
{
  typedef const TChar * citerator;
  static citerator Begin(const TChar(&s)[N]) const { return s; }
  static citerator End (const TChar(&s)[N]) const { return s + N - 1; }
};

Usage:

std::equal(StringBounds<StringType>::Begin(target), StringBounds<StringType>::End(target), begin)


Pass a proper std::string instead.

String literals don't have their own "type"; your input data could be considered to be mangled, essentially.

You could specialise/overload for char const*, which almost universally will be null-terminated.


Your API is a template API. Use template specialization to create specialized versions for char* and actual iterator types.

Also, there is a reason why the C++ standard algorithms deal only in iterators and not containers (like StringType).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜