Есть ли встроенный способ приведения к другому базовому типу, но с сохранением квалификаторов const? - PullRequest
0 голосов
/ 24 октября 2018

Есть ли в стандартной библиотеке C ++ 11/14/17 способ приведения объекта к другому типу, но с теми же квалификаторами cv, что и у исходного объекта?Например,

char* ptr;
const char* cptr;

type_cast<void*>(ptr) должен дать тип void*
type_cast<void*>(cptr) должен дать тип const void*

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Похоже, что нет C ++ 17 или более раннего способа stdlib, чтобы делать то, что вы хотите в одной функции / выражении.Однако, похоже, что в C ++ 20 может быть что-то подобное: https://en.cppreference.com/w/cpp/types/common_reference (недоступно ни в одном из компиляторов, хотя кажется).

РЕДАКТИРОВАТЬ: но оно доступно в Ranges lib, так чтоесли вы уже используете его, вместо него вы можете использовать ranges::common_reference_t.

Но для вашего случая лучше перегрузить константу аргумента или использовать 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

0 голосов
/ 24 октября 2018

Нет в стандартной библиотеке, но, безусловно, можно реализовать ее самостоятельно:

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...