intrigued_66
intrigued_66

Reputation: 17248

Cannot use BOOST_STRONG_TYPEDEF with std::string

I'm using Boost's (v 1.71) strong typedef to differentiate a std::string but I'm having a few problems.

BOOST_STRONG_TYPEDEF(std::string, StrongString);

First, I would like to use StrongString with unordered_map, but when I overload the hash:

std::unordered_map<StrongString, int, std::hash<StrongString>> umap;

I get the compiler error:

/usr/include/c++/11/bits/hashtable_policy.h:1126:7: error: use of deleted function ‘std::hash<StrongString>::~hash()’

Second, previously I was using string concatenation and invoking string::length():

std::string s;
s += "c";
s.length();

However, when I now do:

StrongString s;
s += "c";
s.length();

I get:

error: no match for ‘operator+=’ (operand types are ‘StrongString’ and ‘std::string’ {aka ‘std::__cxx11::basic_string<char>’})

error: StrongString has no member named ‘length’

I can fix the compiler errors by using s.t to access the internal t member of Boost Strong Typedef, but this cannot be the correct way to use it.

Upvotes: 0

Views: 168

Answers (1)

3CxEZiVlQ
3CxEZiVlQ

Reputation: 38539

The aim of BOOST_STRONG_TYPEDEF macro is generating a class that wraps and instance of a primitive type and provides appropriate conversion operators in order to make the new type substitutable for the one that it wraps.

std::string is not a primitive type.

The possible impl:

struct StrongString {
  StrongString(const std::string& s) : wrapped_(s) {}
  operator std::string&() { return wrapped_; }

 private:
  std::string wrapped_;
};

As you can see, StrongString does not have member functions, thus s.length() and += do not work, but this might work: std::size(s) and s = std::string(s) + "c".

std::hash is not defined for StrongString.

Upvotes: 2

Related Questions