2

Sometimes I find myself adding overloads that have the same implementation, with const in qualifier and return value being the only difference:

struct B {};
struct A {
    const B& get(int key) const
    {
        if (auto i = map.find(key); i != map.end())
            return i->second;
        throw std::runtime_error{""};
    }

    B& get(int key)
    {
        if (auto i = map.find(key); i != map.end())
            return i->second;
        throw std::runtime_error{""};
    }

private:
    std::unordered_map<int, B> map;
};

Is there an idiomatic way to write the implementation only once and get rid of copy-paste that is better than const_cast:

const B& get(int key) const
{
    return const_cast<A*>(this)->get(key);
}

?

Dev Null
  • 4,046
  • 1
  • 19
  • 40
  • Good question. Definitely a duplicate. An adequate pattern for this is yet to emerge. Scott Meyers uses the `const_cast` technique. – Bathsheba Sep 21 '18 at 09:47

1 Answers1

1

Scott Meyers' advice:

When const and non-const member functions have essentially identical implementations, code duplication can be avoided by having the non-const version call the const version.

P.W
  • 24,743
  • 6
  • 32
  • 69
  • Not always feasible: `struct Counterexample { int meow() { return 42; } int meow() const { return 314; } int nyan() { return meow(); } int nyan() const { return meow(); } };` – bipll Sep 21 '18 at 10:09
  • Agree. But it may be useful in the OP context. – P.W Sep 21 '18 at 10:12
  • so it's essentially (almost) the same as my example with `const_cast` – Dev Null Sep 21 '18 at 10:27
  • Two casts are used. One is a `static_cast` to add const to *this’s type, so that the const version will be called. and the other is `const_cast` to cast away `const` on the return type. And these casts are used in the non-const version. – P.W Sep 21 '18 at 10:43