相关疑难解决方法(0)

通过void*而不是使用reinterpret_cast进行转换

我正在读一本书而且我发现reinterpret_cast不应该直接使用,而是将其与无效*结合使用static_cast:

T1 * p1=...
void *pv=p1;
T2 * p2= static_cast<T2*>(pv);
Run Code Online (Sandbox Code Playgroud)

代替:

T1 * p1=...
T2 * p2= reinterpret_cast<T2*>(p1);
Run Code Online (Sandbox Code Playgroud)

但是,我找不到解释为什么这比直接演员更好.如果有人能给我一个解释或指出我的答案,我将非常感激.

提前致谢

ps我知道用的是什么reinterpret_cast,但我从未见过以这种方式使用它

c++ casting void-pointers language-lawyer reinterpret-cast

37
推荐指数
2
解决办法
5697
查看次数

使用constexpr解决重新解释的强制转换限制

在c ++ 11中,constexpr表达式不能包含重新解释转换.因此,例如,如果想要操纵浮点数中的位,比如找到数字的尾数:

constexpr unsigned int mantissa(float x) { 
    return ((*(unsigned int*)&x << 9) >> 9); 
};
Run Code Online (Sandbox Code Playgroud)

上面的代码将无法实现constexpr.从理论上讲,我无法看到在这个或类似情况下重新解释如何与算术运算符有任何不同,但编译器(和标准)不允许它.

是否有任何巧妙的方法来解决这个限制?

c++ reinterpret-cast constexpr c++11

25
推荐指数
3
解决办法
8098
查看次数

reinterpret_cast几乎没用吗?

我已经阅读了之前有关使用的reinterpret_cast各种问题,并且我还阅读了C++标准中的相关措辞.本质上,它归结为指针到指针reinterpret_cast操作的结果不能安全地用于除了被回送到原始指针类型之外的任何东西.

然而,在实践中,大多数现实世界的使用reinterpret_cast似乎都是基于(错误的)假设,即a reinterpret_cast与C风格的演员表相同.例如,我见过很多的代码,它使用reinterpret_cast从投char*unsigned char*的字符集转换程序的目的.这是完全无害的,但严格来说,它不是便携式-有没有保证,一个reinterpret_cast来自char*unsigned char*当您尝试取消引用不会崩溃您的程序unsigned char*指针.

根据标准,似乎唯一的其他实际用途reinterpret_cast有任何真正的保证,是从指针转换为整数,反之亦然.

然而,在许多情况下,我们希望(并且应该能够)在不同的指针类型之间安全地进行转换.例如:uint16_t*到新的C++ 0x char16_t*,或者实际上是指向与原始类型相同大小/对齐的基本数据类型的任何指针.然而,reinterpret_cast并不保证这应该起作用.

问题:如何安全地在指向相同大小/对齐的基本数据类型的指针之间进行转换,例如char*- > unsigned char*?既然reinterpret_cast似乎并不保证这实际上有效,那么C风格的演员是唯一安全的选择吗?

c++ pointers casting reinterpret-cast type-punning

16
推荐指数
1
解决办法
3960
查看次数

C++在结构初始化期间给出奇怪的错误,里面有一个数组

我尝试编译非常简单的代码:

struct T {
    int a[3];
    int b;
    int c;
};

int main() {
    const int as[3] = { 5, 6, 7, };
    const T t {
        as, 2, 3,
    };
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但它给了我很奇怪的错误:

t.cpp: In function 'int main()':
t.cpp:11:5: error: array must be initialized with a brace-enclosed initializer
     };
     ^
Run Code Online (Sandbox Code Playgroud)

根据我的理解,编译器希望我在一个地方初始化所有内容.如何单独初始化字段,然后在初始化结构时使用它们?

c++

14
推荐指数
2
解决办法
1728
查看次数

枚举的reinterpret_cast错误

为什么我不能使用reinterpret_cast运算符进行这样的演员表?

enum Foo { bar, baz };

void foo(Foo)
{
}

int main()
{
   // foo(0); // error: invalid conversion from 'int' to 'Foo'
   // foo(reinterpret_cast<Foo>(0)); // error: invalid cast from type 'int' to type 'Foo'
   foo(static_cast<Foo>(0)); 
   foo((Foo)0);
}
Run Code Online (Sandbox Code Playgroud)

c++ enums static-cast

11
推荐指数
1
解决办法
3335
查看次数

reinterpret_cast与static_cast在标准布局类型中写入字节?

我需要写一些整数类型的单个字节.我应该使用reinterpret_cast,还是应该使用static_castvia void*

(一个)

unsigned short v16;
char* p = static_cast<char*>(static_cast<void*>(&v16));
p[1] = ... some char value
p[0] = ... some char value
Run Code Online (Sandbox Code Playgroud)

或(b)

unsigned short v16;
char* p = reinterpret_cast<char*>(&v16);
p[1] = ... some char value
p[0] = ... some char value
Run Code Online (Sandbox Code Playgroud)

根据static_cast和reinterpret_cast对std :: aligned_storage回答都应该是等价的 -

- 如果T1和T2都是标准布局类型,并且T2的对齐要求不比T1更严格

我倾向于reinterpret_cast基本上我在做什么,不是吗?

还有其他需要考虑的事情,特别是我们正在编译的Visual-C++和VC8版本吗?(x86只有atm.)

c++ reinterpret-cast visual-c++-2005 standard-layout c++11

9
推荐指数
1
解决办法
900
查看次数

用C++重新解释这个:合法与否?

这是一个有点深奥的问题,但我很好奇以下类扩展模式在现代C++中是否合法(如,不构成UB)(出于所有目的和目的,我将讨论局限于C++ 17和后来).

template<typename T>
struct AddOne {
    T add_one() const {
        T const& tref = *reinterpret_cast<T const*>(this);
        return tref + 1;
    }
};

template<template<typename> typename  E, typename T>
E<T> const& as(T const& obj) {
    return reinterpret_cast<E<T> const&>(obj);
} 

auto test(float x) {
    return as<AddOne>(x).add_one();
}

auto test1(int x) {
    return as<AddOne>(x).add_one();
}

// a main() to make this an MVCE
// will return with the exit code 16
int main(int argc, const char * argv[]) {
  return test1(15);
}
Run Code Online (Sandbox Code Playgroud)

上面的代码是一个完整的例子,它在C++ …

c++ language-lawyer reinterpret-cast c++17

9
推荐指数
2
解决办法
529
查看次数

虚函数并转换为void和back

目前我正在使用传统的c ++代码库.在此代码库中,指向对象的指针将转换为void-pointers,然后存储在c-library中.请考虑以下代码:

class interface {
public:
  virtual void foo() {
    std::cout << "Interface" << std::endl;}
  virtual ~interface(){};
};

class debug_interface: public interface {
public:
  virtual void foo() {
   std::cout << "Debug Interface" << std::endl;}
};
Run Code Online (Sandbox Code Playgroud)

对象interfacedebug_interface在堆上分配,地址存储在void指针中.在某些时候,指针被检索,然后再转换回基类interface.然后调用虚函数调用.看到

int main(int argc, char *argv[]){

    void *handle = reinterpret_cast<void*>(new interface());
    void *debug_handle = reinterpret_cast<void*>(new debug_interface());

   //void *handle = new interface();
   //void *debug_handle = new debug_interface();

   interface *foo1 = reinterpret_cast<interface*>(handle);
   interface *foo2 = reinterpret_cast<interface*>(debug_handle);

   //interface *foo1 = static_cast<interface*>(handle);
   //interface …
Run Code Online (Sandbox Code Playgroud)

c++ virtual void static-cast reinterpret-cast

8
推荐指数
1
解决办法
1059
查看次数

reinterpret_cast无效是合法的*

我正在查看https://en.cppreference.com/w/cpp/language/reinterpret_cast,我注意到它指定了我们可以始终转换为的合法类型:

  • byte*
  • char*
  • unsigned char*

但我并没有看到void*在列表中。这是疏忽吗?我的用例需要一个,reinterpret_cast因为我是从int**转换为void*。我最终会从void*后面投射到镜头上int**

c++ pointers void-pointers double-pointer reinterpret-cast

8
推荐指数
2
解决办法
323
查看次数

使用C++样式转换从Void*转换为TYPE*:static_cast或reinterpret_cast

因此,如果您从Void*转换为Type*或从Type*转换为Void*,您应该使用:

void func(void *p)
{
    Params *params = static_cast<Params*>(p);
}
Run Code Online (Sandbox Code Playgroud)

要么

void func(void *p)
{
    Params *params = reinterpret_cast<Params*>(p);
}
Run Code Online (Sandbox Code Playgroud)

对我来说static_cast似乎更正确,但我看到两者都用于同一目的.此外,转换的方向是否重要.即我还应该使用static_cast:

_beginthread(func,0,static_cast<void*>(params)
Run Code Online (Sandbox Code Playgroud)

我已经阅读了关于C++样式转换的其他问题但是我仍然不确定这个场景的正确方法是什么(我认为它是static_cast)

c++ casting static-cast reinterpret-cast

7
推荐指数
1
解决办法
5499
查看次数