C-> C++在#define中自动将void指针转换为C++中的Type指针,如果没有给出类型(C风格)[MSVS]

zxc*_*cat 7 c c++ casting void-pointers visual-c++

嗨!

我使用了以下C宏,但在C++中它无法自动转换void*type*.

#define MALLOC_SAFE(var, size) { \
    var = malloc(size); \
    if (!var) goto error; \
}
Run Code Online (Sandbox Code Playgroud)

我知道,我可以这样做:

#define MALLOC_SAFE_CPP(var, type, size) { \
    var = (type)malloc(size); \
    if (!var) goto error; \
}
Run Code Online (Sandbox Code Playgroud)

但我不想重写大部分代码,MALLOC_SAFE使用的地方.

有没有办法在没有给宏的类型的情况下这样做?也许一些MSVC 2005 #pragma/__declspec/其他?

ps:我不能使用C编译器,因为我的代码是大项目的一部分(数百个模块之一).现在它是在C++上.我知道,我可以单独构建我的代码.但这是旧代码,我只是想快速移植它.

问题是关于void*cast;)如果不可能,我只需用MACRO_SAFE_CPP替换MACRO_SAFE

谢谢!

GMa*_*ckG 34

为了让詹姆斯的回答更加肮脏,如果你没有decltype支持,你也可以这样做:

template <typename T>
class auto_cast_wrapper
{
public:
    template <typename R>
    friend auto_cast_wrapper<R> auto_cast(const R& x);

    template <typename U>
    operator U()
    {
        return static_cast<U>(mX);
    }

private:
    auto_cast_wrapper(const T& x) :
    mX(x)
    {}

    auto_cast_wrapper(const auto_cast_wrapper& other) :
    mX(other.mX)
    {}

    // non-assignable
    auto_cast_wrapper& operator=(const auto_cast_wrapper&);

    const T& mX;
};

template <typename R>
auto_cast_wrapper<R> auto_cast(const R& x)
{
    return auto_cast_wrapper<R>(x);
}
Run Code Online (Sandbox Code Playgroud)

然后:

#define MALLOC_SAFE(var, size)                      \
{                                                   \
    var = auto_cast(malloc(size));                  \
    if (!var) goto error;                           \
}
Run Code Online (Sandbox Code Playgroud)

我在我的博客上扩展了这个实用程序(在C++ 11中).不要用它来做任何事情,除了邪恶.

  • 我不知道是投票还是投票. (17认同)
  • @R:C++中有什么破坏`void*`的行为?鉴于它是一种静态类型语言,我必须批准任何类型安全的动作,并且你很少需要在C++中使用`void*`. (8认同)
  • 同样正如大卫所说的那样,我看不出有关静态类型语言需要你尊重静态类型系统的"破坏".我知道有些人不喜欢听到这个,但语言可能与C**不同,同时也不会被打破**. (5认同)
  • @GMan,谢谢.但是你的头脑吓到了我:) (4认同)
  • 我已经看到第一个真正的解决方案+1了C++的破坏`void*`行为. (3认同)

Jam*_*lis 13

我不建议这样做; 这是可怕的代码,如果您使用C,您应该使用C编译器(或者,在Visual C++中,作为C文件)编译它

如果您使用的是Visual C++,则可以使用decltype:

#define MALLOC_SAFE(var, size)                      \
{                                                   \
    var = static_cast<decltype(var)>(malloc(size)); \
    if (!var) goto error;                           \
}
Run Code Online (Sandbox Code Playgroud)

  • 另一个要注意的是,宏绝不应该是“ {...}”,而是使用`do {...} while(0)`更为安全。在任何可能带有尾随的`;`和`if else`块的情况下,它将表现得更好。 (3认同)

Unc*_*ens 5

例如,像这样:

template <class T>
void malloc_safe_impl(T** p, size_t size)
{
    *p = static_cast<T*>(malloc(size));
}

#define MALLOC_SAFE(var, size) { \
    malloc_safe_impl(&var, size); \
    if (!var) goto error; \
}
Run Code Online (Sandbox Code Playgroud)