Violet Giraffe
Violet Giraffe

Reputation: 33589

Is there a built-in way to cast to a different underlying type but preserve const qualifiers?

Does the C++11/14/17 standard library have a way to cast an object to a different type but with the same cv-qualifiers as the original object? E. g.

char* ptr;
const char* cptr;

type_cast<void*>(ptr) should yield the type void*
type_cast<void*>(cptr) should yield the type const void*

Upvotes: 3

Views: 277

Answers (2)

Quentin
Quentin

Reputation: 63124

Not in the standard library, but it is certainly possible to implement it yourself:

namespace detail_base_type_cast {
    template <class In, class Out>
    struct copy_cv {
        using type = Out;
    };

    template <class In, class Out>
    struct copy_cv<In const, Out &> {
        using type = Out const &;
    };

    template <class In, class Out>
    struct copy_cv<In volatile, Out &> {
        using type = Out volatile &;
    };

    template <class In, class Out>
    struct copy_cv<In const volatile, Out &> {
        using type = Out const volatile &;
    };
}

template <class Out, class In>
typename detail_base_type_cast::copy_cv<In, Out>::type
base_type_cast(In &obj) {
    return obj; // Implicit derived-to-base conversion
}

Upvotes: 3

Dan M.
Dan M.

Reputation: 4052

It looks like there is no C++17 or earlier stdlib way to do what you want in single function/statement. However it looks like there might be something like this in C++20: https://en.cppreference.com/w/cpp/types/common_reference (not available in any of the compilers yet it seems).

EDIT: but it's available in Ranges lib so if you already use it, you can use ranges::common_reference_t instead.

But for your use case, either overloading on argument constness or using if constexpr might be a better option.

I.e. something like:

template<typename T>
auto foo(T &bar) {
    // lots of code

    if constexpr(std::is_const_v<T>) {
        return static_cast<const Foo&>(bar);
    } else {
        return static_cast<Foo&>(bar);
    }
}

https://godbolt.org/z/dbCUdM

Upvotes: -1

Related Questions