gcc深/双/嵌套铸造

gcc deep/double/nested casting

本文关键字:嵌套 gcc      更新时间:2023-10-16

首先是代码

#include <stdio.h>
typedef wchar_t* BSTR;
wchar_t hello[] = L"Hello";
class _bstr_t {
public:
    operator const wchar_t*() const throw() { return hello; }
    operator wchar_t*() const throw() { return hello; }
};
class container {
public:
    operator _bstr_t() { return _bstr_t(); }
};
int main()
{
    // This gives error (with gcc 4.5.2 at least):
    // test.cpp:20:27: error: cannot convert "container" to "wchar_t*" in initialization
    wchar_t *str = container();
    printf("%Sn", str);
    return 0;
}

这里的问题是container()可以被广播到_bstr_t,然后再广播到wchar_t*,但是gcc不能。

该问题可以使用手动铸造解决:

wchar_t *str = (_bstr_t)container();

但我需要的是避免手动强制转换,我希望gcc能自动解决这个问题。

我之所以需要这个是因为返回的容器类型对象将用于之类的调用

void Func(wchar_t* str);
Func(myObject->Container);

我不想做手动选角。

我验证了Visual Studio,它似乎也不支持这样的场景。太糟糕了,但如果有人能提供一个变通办法,我会很高兴,即使是在这个特定的情况下。

更新:对于那些建议在容器上使用运算符wchar_t*的人,认为首先是问题所在。当在Func()有机会接受指针之前被销毁时,它将泄漏或崩溃。

在进行隐式转换时,最多可以进行一次用户定义的转换。MSVC的行为在这件事上不符合标准。

C++11(12.3转换):

最多一个用户定义的转换(构造函数或转换函数)隐式应用于单个值。

为了使隐式转换工作,container必须直接转换为wchar_t*

它不起作用,因为类容器没有operator wchar_t*()。唯一的解决方案是将其添加到容器类:

#include <iostream>
typedef wchar_t* BSTR;
wchar_t hello[] = L"Hello";

class container {
public:
    operator const wchar_t*() const throw() { return hello; }
    operator wchar_t*() const throw() { return hello; }
};
int main()
{
    // This gives error (with gcc 4.5.2 at least):
    // test.cpp:20:27: ошибка: cannot convert «container» to «wchar_t*» in initialization
    wchar_t *str = container();
    std::wcout<<str<<std::endl;
}

您没有从wchar_t *container的转换器,这就是为什么您会得到错误

class container {
public:
  operator wchar_t*() { return _bstr_t(); }
};