0

Sure, the std::string interface is already bloated. But it's missing some (for me) crucial elements. For example, a std::wstring cannot be constructed from a plain const char* (which is what is needed to create one from a string literal). I'd also like to add an operator/ and a split function. Anyways, that's all besides the point of the question. Which is preventing me writing a core class's guts for a project.

I know I can privately inherit from std::(w)string, and "import" all members with using. This misses the crucial non-member template functions, which are numerous.

How can I approach this better? I know public inheritance "solves" the problem, but it introduces the problems of deleteing a base class pointer of a class without a virtual destructor. Note that I'm not planning to add data members, so is this really a problem, or is this corner case still fine to use public inheritance?

Please don't say "don't do this", unless you can provide a way that 1) does what I want, 2) doesn't require me to write it all myself, 3) does not bloat my caller-side interface.

5
  • 2
    "(which is what is needed to create one from a string literal)" What about wide string literals? Commented Jan 3, 2014 at 21:20
  • 2
    To first order, std::wstring shouldn't be used at all; to second order, what's wrong with writing 'std::wstring foo(L"foo")'? Your split and operator/ (what does it even mean to divide strings?!) can perfectly well be free functions, can't they? Commented Jan 3, 2014 at 21:23
  • 1
    @DyP: I don't care about those. Just plain text string literals in any place you'd normally use them. I want to use wstring on Windows and string everywhere else, but I want to use standard interfaces, so no special tcout and tchar. It's very much possible, there's enough typedefs to hide the underlying type's real name. Commented Jan 3, 2014 at 21:23
  • 1
    You should instead use string (containing UTF-8) everywhere including Windows, converting to "wide"ness only to pass directly to or from Win32 API functions that require it. Commented Jan 3, 2014 at 21:25
  • @rubenvb: That's not gonna happen (and really the wrong approach). You need to pick one encoding, like UTF-8 or UTF-16, and use it everywhere on all platforms, and then convert in/out of OS APIs on the platforms where they don't match. The existing design simply doesn't really support what you want to do. Commented Jan 3, 2014 at 21:25

1 Answer 1

11

Do not derive from std::basic_string<...> but rather create algorithms doing the appropriate operations, e.g.:

template <typename cT>
std::basic_string<cT> construct(char const* str) {
    // ...
}

Likewise for split(), operator/(), etc. In principle, most members of std::basic_string<...> shouldn't be members in the first place...

Sign up to request clarification or add additional context in comments.

3 Comments

I stress that I do not want to bloat my caller-side interface. This is terrible in that respect. I agree it's better design-wise, but it'll produce a lot of wrapper code... I added this as point 3.
@rubenvb: I disagree. Member functions for anything but non-crucial object maintenance is plain wrong.
I don't understand why free functions of the form vector<string> split(string const& text, const char *separator) would "bloat your caller-side interface" any more than hypothetical new string members would. You've already been told what to do about constructing wstring from const char * (i.e. "don't").

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.