是否有内置的方法来强制转换为其他基础类型,但保留const限定符?

时间:2018-10-24 13:26:45

标签: c++ type-conversion const c++17

C ++ 11/14/17标准库是否可以将对象转换为其他类型,但具有与原始对象相同的cv限定符?例如:

char* ptr;
const char* cptr;

type_cast<void*>(ptr)应该产生类型void*
type_cast<void*>(cptr)应该产生类型const void*

2 个答案:

答案 0 :(得分:2)

不在标准库中,但是可以自己实现:

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<In, Out>::type
base_type_cast(In &obj) {
    return obj; // Implicit derived-to-base conversion
}

答案 1 :(得分:-1)

似乎没有C ++ 17或更早的stdlib方法可以在单个函数/语句中完成所需的操作。 但是,看起来C ++ 20中可能有这样的东西:https://en.cppreference.com/w/cpp/types/common_reference(似乎尚未在任何编译器中提供)。

编辑:但是它在Ranges lib中可用,因此,如果您已经使用它,则可以改用ranges::common_reference_t

但是对于您的用例,要么在参数constness上重载,要么使用if constexpr可能是一个更好的选择。

即像这样:

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