如何在任何两种类型之间进行reinterpret_cast?

时间:2019-05-31 11:09:20

标签: c++ c++11 reinterpret-cast

我想重新声明一个给定变量的类型,但是不幸的是rerequire_cast <>在这里没有帮助。这行:

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

导致以下编译器错误:

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

是否有其他干净的方法?

注意:

  • 我知道reinterpret_cast <>是不正确的转换。我真的只想在这里重新声明类型。此行周围的一些代码将确保仅在适当的时候执行
  • 为什么上面的这行实际上不起作用?
  • 我知道这个选项,我认为它太乱了:* reinterpret_cast(&OldType)

编辑/某些上下文:此行将是模板化函数的一部分,具有:

{{1}}

对于T == std :: string,这是完全可以的,但是不幸的是,编译器还将尝试实例化T == std :: vector <>(但在运行时从不使用)。这是C ++ 11,因此没有static_if。

3 个答案:

答案 0 :(得分:5)

您不能,这样做没有任何意义,编译器告诉您。

reinterpret_cast不能将一种类型分为完全不相关的类型。

即使这样做,例如您在最后的要点中出现的指针黑客行为,该语言的规则也禁止您使用经过这种强制转换的对象。

根本不做,因为你做不到。

如果您试图从字符串(?)构造一个双精度向量,请按照业务需求规定的方式编写相应代码以从字符串中产生双精度。

类型系统可以为您提供帮助。放手吧。

答案 1 :(得分:2)

  

对于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...
    }
    // ...
}

在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);

    // ...
}

答案 2 :(得分:0)

You want to construct a container from a string literal.

Use a different constructor overload, e.g.

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

Which is compatible with

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

Thusly

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

See it live