Is it possible to parameterize the constness of a templated member function?

c++, c++11, c++14, constants, templates

Solution

But is it also possible to parameterize the constness of a member function?

No, you cannot. You don't have access in the function signature to the implicit object to which `this` points, so you can't dispatch on it or template on it in any way. cv-qualifiers on member functions have to be spelled out.

For more complicated member functions, you could have one invoke the other (typically the non-`const` invoking the `const` one to avoid UB) to avoid some code duplication.

Or you could always write a non-member `friend`:

struct Foo {
    template <class T,
        std::enable_if_t<std::is_base_of<Foo, std::decay_t<T>>::value>* = nullptr
        >
    friend T* self(T& x) { return &x; }
};

We need the SFINAE to ensure that `self()` isn't found for unexpected types like `Wrapper<Foo>`. Note that this is quite a big longer than your original code, so really only makes sense in the context of having complicated logic.

Would sure be amusing if UFCS was adopted and now we all write our `const`/non-`const` overloads via non-member `friend`s that we still invoke as if they were members.

Problem

Templates make most things about a function signature parameterizable apart from the function name itself. But is it also possible to parameterize the constness of a member function? Trivial, minimalist, non-templated example: ``` struct Foo { Foo * self() { return this; } Foo const * self() const { return this; } }; ``` vs straw-man templated hypothetical: ``` struct Foo { template<typename T> T self() std::constness_of(T) { return this; } }; ```

Original source