GCC глубокое / двойное / вложенное литье - PullRequest
0 голосов
/ 11 января 2012

Сначала код

#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("%S\n", 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 () сможет принять указатель.

Ответы [ 3 ]

6 голосов
/ 11 января 2012

При выполнении неявных преобразований может быть не более одного пользовательского преобразования, которое может произойти. Поведение MSVC не соответствует стандарту в этом вопросе.

C ++ 11 (12,3 преобразования):

Не более одного определенного пользователем преобразования (конструктор или функция преобразования) неявно применяется к одному значению.

Чтобы неявное преобразование работало, container необходимо преобразовать непосредственно в wchar_t*.

1 голос
/ 11 января 2012

Не работает, потому что контейнер класса не имеет 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;
}
0 голосов
/ 11 января 2012

У вас нет конвертера из wchar_t * в container, поэтому вы получаете ошибку

class container {
public:
  operator wchar_t*() { return _bstr_t(); }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...