我如何在任意两种类型之间 reinterpret_cast ?
How do I reinterpret_cast between any two types?
我想重新声明给定变量的类型,但不幸的是 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)
Edit/Some 上下文:此行将成为模板函数的一部分,具有:
reinterpret_cast<T>(std::string())
对于 T == std::string 这完全没问题,但不幸的是,编译器也会尝试为 T == std::vector<> 实例化(但在运行时从不使用)它。而且这是 C++11,所以没有 static_if。
你不能,这样做没有意义,编译器告诉你了。
reinterpret_cast
不能将一个类型破解成完全不相关的类型。
即使是这样,例如您在最后一个要点中展示的指针 hackery,该语言的规则也禁止您使用经过此类转换的对象。
干脆不做,因为你做不到。
如果您尝试从字符串 (?) 构建双精度值向量,那么请按照您的业务要求所规定的方式编写适当的代码以从字符串中生成双精度值。
类型系统可以帮助您。放吧。
您想从字符串文字构造一个容器。
使用不同的构造函数重载,例如
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) }
For T == std::string this is completely fine, but unfortunately the compiler will also try to instantiate (but at runtime never use) it for T == std::vector<>. And this is C++11, so there is no 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);
// ...
}
我想重新声明给定变量的类型,但不幸的是 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)
Edit/Some 上下文:此行将成为模板函数的一部分,具有:
reinterpret_cast<T>(std::string())
对于 T == std::string 这完全没问题,但不幸的是,编译器也会尝试为 T == std::vector<> 实例化(但在运行时从不使用)它。而且这是 C++11,所以没有 static_if。
你不能,这样做没有意义,编译器告诉你了。
reinterpret_cast
不能将一个类型破解成完全不相关的类型。
即使是这样,例如您在最后一个要点中展示的指针 hackery,该语言的规则也禁止您使用经过此类转换的对象。
干脆不做,因为你做不到。
如果您尝试从字符串 (?) 构建双精度值向量,那么请按照您的业务要求所规定的方式编写适当的代码以从字符串中生成双精度值。
类型系统可以帮助您。放吧。
您想从字符串文字构造一个容器。
使用不同的构造函数重载,例如
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) }
For T == std::string this is completely fine, but unfortunately the compiler will also try to instantiate (but at runtime never use) it for T == std::vector<>. And this is C++11, so there is no 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);
// ...
}