Как я могу reinterpret_cast между любыми двумя типами? - PullRequest
0 голосов
/ 31 мая 2019

Я хотел бы повторно объявить тип данной переменной, но, к сожалению, reinterpret_cast <> здесь не помогает.Эта строка:

reinterpret_cast<std::vector<double>>(std::string("Hello"));

приводит к следующей ошибке компилятора:

invalid cast from type 'std::string {aka std::basic_string<char>}' to type 'std::vector<double>'

Есть ли другой, чистый подход?

Примечания:

  • Я знаю, что reinterpret_cast <> не является правильным преобразованием.Я действительно только хочу повторно объявить тип здесь.Некоторый код в этой строке будет гарантировать, что он выполняется только тогда, когда это уместно
  • Почему на самом деле эта строка выше не работает?
  • Мне известна эта опция, которая, на мой взгляд, слишком запутанна: *reinterpret_cast (& OldType)

Редактировать / Некоторый контекст: Эта строка будет частью шаблонной функции с:

reinterpret_cast<T>(std::string())

Для T == std :: string это полностьюхорошо, но, к сожалению, компилятор также попытается создать экземпляр (но во время выполнения никогда не использовать) его для T == std :: vector <>.И это C ++ 11, поэтому нет static_if.

Ответы [ 3 ]

5 голосов
/ 31 мая 2019

Вы не можете, это не имеет смысла, и компилятор сказал вам, что.

reinterpret_cast не может взломать тип на совершенно не связанный тип.

Даже если это произойдет, например, с помощью хакерских указателей, которые вы демонстрируете в своем последнем пункте, правила языка запрещают вам использовать объект, подвергшийся такому приведению.

Просто не делайте этого, потому что вы можете't.

Если вы пытаетесь построить вектор двойных чисел из строки (?), то сделайте именно это, написав соответствующий код для получения двойных чисел из вашей строки, в порядке, запрещенном вашей компанией.требования.

Система типов поможет вам.Пусть это.

2 голосов
/ 31 мая 2019

Для T == std :: string это вполне нормально, но, к сожалению, компилятор также попытается создать экземпляр (но во время выполнения никогда не использовать) его для T == std :: vector <>.И это C ++ 11, поэтому нет static_if.

В C ++ 17, как вы сказали, вы можете использовать if constexpr:

template <typename T>
void foo(const T& value)
{
    bar(value);

    if constexpr (std::is_same<std::string, T>::value) {
        // Specific code for string
    } else constexpr (std::is_same<std::vector<int>, T>::value) {
        // specific code for vector...
    }
    // ...
}

Priorдо C ++ 17 вы можете использовать перегрузки, возможно с диспетчеризацией тегов, SFINAE.

void foo_specific(const std::string& s)
{
    // Specific code for string
}

void foo_specific(const std::vector<T>& v)
{
    // Specific code for vector
}

template <typename T, std::enable_if_t<std::is_integral<T>::value>, int> = 0>
void foo_specific(const T& n)
{
    // Specific code for integral
}

// ...

template <typename T>
void foo(const T& value)
{
    bar(value);

    foo_specific(value);

    // ...
}
0 голосов
/ 31 мая 2019

Вы хотите создать контейнер из строкового литерала.

Использовать другую перегрузку конструктора, например

template< class InputIt >
basic_string( InputIt first, InputIt last, const Allocator& alloc = Allocator());

, которая совместима с

template< class InputIt >
vector( InputIt first, InputIt last, const Allocator& alloc = Allocator() );

Таким образом

char hello[] = "Hello";
T{ std::begin(hello), std::end(hello) }

Посмотреть вживую

...