Проблема GCC со static_cast - PullRequest
       1

Проблема GCC со static_cast

0 голосов
/ 17 октября 2018

Сводка

У меня есть класс, к которому я добавил оператор преобразования типов для преобразования в std::u16string.Сигнатура этого оператора выглядит следующим образом:

operator const std::u16string() const;

В моем файле .cpp я пытаюсь преобразовать объект типа моего класса в std::u16string следующим образом:

std::u16string sUTF16Password = static_cast<std::u16string>(Password_);

Вкл.Visual Studio 2017, это работает просто отлично.Тем не менее, GCC 6.3 на моем Raspberry Pi выдает следующую ошибку во время компиляции:

error :  call of overloaded 'basic_string(MyClass&)' is ambiguous

Как правильно написать этот тип передачи?Поиск в Google приносит много хитов для преобразования кодировки символов, но это не моя проблема здесь.Я не понимаю, почему конструктор basic_string вызывается здесь, несмотря на использование static_cast.

Полный пример

Вот минимальный пример.Скомпилировать его с помощью g++ main.cpp не удалось на моем Raspberry Pi.

#include <iostream>
#include <string>

class MyClass
{
    private:
        std::u16string Str;
    public:
        MyClass() { Str = u"abcd"; }
        operator const char16_t*() const { return Str.c_str(); }
        operator std::u16string() const { return Str; }
};

int main()
{
    MyClass Tester;
    std::u16string TestStr = static_cast<std::u16string>(Tester);
    for (size_t idx = 0; idx < TestStr.size(); idx++)
        std::cout << idx << ": " << TestStr[idx] << std::endl;
    return 0;
}

Вывод gcc --version равен gcc (Raspbian 6.3.0-18+rpi1+deb9u1) 6.3.0 20170516.

Полный вывод g++ main.cpp:

main.cpp: In function ‘int main()’:
main.cpp:17:61: error: call of overloaded ‘basic_string(MyClass&)’ is ambiguous
  std::u16string TestStr = static_cast<std::u16string>(Tester);
                                                             ^
In file included from /usr/include/c++/6/string:52:0,
                 from /usr/include/c++/6/bits/locale_classes.h:40,
                 from /usr/include/c++/6/bits/ios_base.h:41,
                 from /usr/include/c++/6/ios:42,
                 from /usr/include/c++/6/ostream:38,
                 from /usr/include/c++/6/iostream:39,
                 from main.cpp:1:
/usr/include/c++/6/bits/basic_string.h:476:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::__cxx11::basic_string<_
CharT, _Traits, _Alloc>&&) [with _CharT = char16_t; _Traits = std::char_traits<char16_t>; _Alloc = std::allocator<char16_t>]
       basic_string(basic_string&& __str) noexcept
       ^~~~~~~~~~~~
/usr/include/c++/6/bits/basic_string.h:454:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&
) [with _CharT = char16_t; _Traits = std::char_traits<char16_t>; _Alloc = std::allocator<char16_t>]
       basic_string(const _CharT* __s, const _Alloc& __a = _Alloc())
       ^~~~~~~~~~~~
/usr/include/c++/6/bits/basic_string.h:397:7: note: candidate: std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::__cxx11::basic_st
ring<_CharT, _Traits, _Alloc>&) [with _CharT = char16_t; _Traits = std::char_traits<char16_t>; _Alloc = std::allocator<char16_t>]
       basic_string(const basic_string& __str)
       ^~~~~~~~~~~~

Если я удаляю приведение типа к const char16_t*, этот пример компилируется просто отлично.Я до сих пор не понимаю, почему наличие обоих типов является проблемой.

1 Ответ

0 голосов
/ 17 октября 2018

Если вы скомпилируете как C ++ 14 (или ранее), вы получите этот неоднозначный вызов, потому что std::u16string(char16_t*) участвует в разрешении перегрузки (через MyClass::operator const char16_t*()), а также MyClass::operator std::u16string(), что будет для лучшего соответствия .

Это можно преодолеть несколькими способами:

  • Компилировать как C ++ 17 (или позже) с GCC 7 или новее (к сожалению)это не помогает в GCC 6).
  • Удалить operator const char16_t*().
  • Добавить explicit к operator const char16_t*() (или к обоим операторам преобразования).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...