Portál AbcLinuxu, 6. května 2025 14:50
Tak jsem narazil na další problém s GCC.
template<typename T> class BaseString{ protected: ... public: ... T& operator[]( unsigned int pos ); const T& operator[]( unsigned int pos ) const; // V tomhle bude problém operator T*(); operator const T*() const; };
V kódu je následující:
// pathW je BaseString<wchar_t>, DIR_SLASH je define L'/' nebo L'\\' dle systému return ( pathW.length() == 1 && pathW[0] == DIR_SLASH );
A co se dá čekat od GCC jiného než
./Toolkit/FileUtils.cpp:120: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: ./Toolkit/String.h:378: note: candidate 1: T& Toolkit::BaseString<T>::operator[](unsigned int) [with T = wchar_t] ./Toolkit/FileUtils.cpp:120: note: candidate 2: operator[](wchar_t*, int) <built-in>
Proč dopr*ele se snaží o ten vestavěný operátor. Zase se prostě rozhodl, že je možné přetypovat BaseString<wchar_t> na wchar_t*, tak hned začal dělat chytrého a cpe mi to. Já se ho ale neprosil. Teď jak z toho ven. Ten operátor k přetypování je pro mě životně důležitý a funkci kvůli tomu tam nechci.
Tiskni
Sdílej:
Ne, není. Zkuste si toto
#define DIR_SLASH L'/' template<typename T> class BaseString{ protected: public: unsigned length() const { return 0; } T& operator[]( unsigned int pos ); const T& operator[]( unsigned int pos ) const; // V tomhle bude problém operator T*(); operator const T*() const; }; typedef BaseString<wchar_t> wstr; bool isslash(const wstr& pathW) { return ( pathW.length() == 1 && pathW[0] == DIR_SLASH ); }
uložit do souboru a přeložit (nelinkovat). Mé gcc ani nepípne, dokonce ani s -Wall
Problém je tedy někde jinde než v tom, co jste nám ukázal.
$ g++ -c -Wall test.cpp test.cpp: In function ‘bool isslash(const wstr&)’: test.cpp:20: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: test.cpp:9: note: candidate 1: const T& BaseString<T>::operator[](unsigned int) const [with T = wchar_t] test.cpp:20: note: candidate 2: operator[](const wchar_t*, int) <built-in> test.cpp:20: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: test.cpp:9: note: candidate 1: const T& BaseString<T>::operator[](unsigned int) const [with T = wchar_t] test.cpp:20: note: candidate 2: operator[](const wchar_t*, int) <built-in>
0L
', pak by to mohlo přesně odpovídat deklaraci.
imho, co tam ten operator pretypovania (a dokonca const) na pointer robi? Kandiduje na uchylku roku?
Zase se prostě rozhodl, že je možné přetypovat BaseString<wchar_t> na wchar_t*, tak hned začal dělat chytrého a cpe mi to. Já se ho ale neprosil
#include <wchar.h> #include <memory> class WideString{ protected: wchar_t* buffer; public: WideString( const wchar_t *text ) { buffer = wcsdup(text); } ~WideString() { free(buffer); } wchar_t& operator[](unsigned int pos) { return buffer[pos]; } const wchar_t& operator[](unsigned int pos) const { return buffer[pos]; } operator wchar_t*() { return buffer; } operator const wchar_t*() const { return buffer; } }; int main( int argc, char **argv ) { WideString str( L"TESTIK" ); if( str[0] == L'T' ) str[0] = L't'; return 0; }
[mikos@tauri temp]$ g++ -c -Wall test.cpp test.cpp: In function ‘int main(int, char**)’: test.cpp:41: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: test.cpp:17: note: candidate 1: wchar_t& WideString::operator[](unsigned int) test.cpp:41: note: candidate 2: operator[](wchar_t*, int) <built-in> test.cpp:41: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: test.cpp:17: note: candidate 1: wchar_t& WideString::operator[](unsigned int) test.cpp:41: note: candidate 2: operator[](wchar_t*, int) <built-in> test.cpp:41: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: test.cpp:17: note: candidate 1: wchar_t& WideString::operator[](unsigned int) test.cpp:41: note: candidate 2: operator[](wchar_t*, int) <built-in> test.cpp:41: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: test.cpp:17: note: candidate 1: wchar_t& WideString::operator[](unsigned int) test.cpp:41: note: candidate 2: operator[](wchar_t*, int) <built-in>A jen pro zajímavost GCC 3.3.6:
[mikos@tauri temp]$ g++3 -c -Wall test.cpp test.cpp: In function `int main(int, char**)': test.cpp:41: error: ISO C++ says that `wchar_t& WideString::operator[](unsigned int)' and `operator[]' are ambiguous even though the worst conversion for the former is better than the worst conversion for the latter test.cpp:41: error: ISO C++ says that `wchar_t& WideString::operator[](unsigned int)' and `operator[]' are ambiguous even though the worst conversion for the former is better than the worst conversion for the latter test.cpp:41: error: ISO C++ says that `wchar_t& WideString::operator[](unsigned int)' and `operator[]' are ambiguous even though the worst conversion for the former is better than the worst conversion for the latter test.cpp:41: error: ISO C++ says that `wchar_t& WideString::operator[](unsigned int)' and `operator[]' are ambiguous even though the worst conversion for the former is better than the worst conversion for the latter
Nicméně je opravdu velmi zvláštní, že vám to prošlo bez problémů...Vidím to na architekturu...
sizeof(int) != sizeof(long)
0U
' (nebo operátor []
deklaruje jako int
), projde to i s -m32
.
int main( int argc, char **argv ) { WideString str( L"TESTIK" ); free(str); return 0; }
s/Mně/Mě/g
, 2. a 4. pár = mě, 3. a 6. pád = mně.
s/Popraveno/Opraveno/g
.
wchar_t
není schopen pokrýt potřebný rozsah znaků?
To není špatný předpoklad, protože je to předpoklad, vycházející ze specifikace jazyků C
3.7.3 wide character
bit representation that fits in an object of type wchar_t
, capable of representing any
character in the current locale
a C++
3.9.1.5 Type wchar_t is a distinct type whose values can represent distinct codes for all members of the largest extended character set specified among the supported locales (22.1.1).
Takže trvám na tom, že je-li něco špatně, je to implementace widestringů ve Windows (vypadá-li tak, jak tvrdíte). Kdyby totiž měl být wchar_t
16-bitový typ a widestringy by měly být v UTF-16, nemělo by smysl je vůbec zavádět, protože by proti klasickým stringům v UTF-8 naprosto nic nepřinášely.
wchar_t
je datový typ, který pokrývá celý rozsah znakové sady používaného locale, takže jeden wchar_t
podle specifikace jazyka odpovídá jednomu znaku (to je také důvod, proč byly vůbec wchar_t
a widestring zaveden). Tak je ten typ definován a tak má fungovat. Pokud tak někde nefunguje, není to korektní implementace ISO C resp. ISO C++.
#include <stdio.h> #include <wchar.h> int main(int arg, char* argv[]) { printf("%u\n", sizeof(wchar_t)); return 0; }výstup:
2kompilováno ve win, pod gcc i ve visual studiu, ahoja
Jestli má frčet aplikace jen pod linuxem, není co řešit.Správně jste měl říct: "Jestli má frčet aplikace pod jakýmkoliv rozumným operačním systémem, není co řešit."
wchar_t
specifikaci sám o sobě neodporuje. Pokud pokryje celý rozsah použité znakové sady a pokud jeden widechar bude jeden znak, je to v pořádku. Chybou je, pokud bude jeden znak zapisován více widechary, tj. začne se zavádět nějaký "multi-widechar string", který v sobě spojí nevýhody MBS a WCS.
wchar_t
a WCS zaveden, je to, aby bylo možné opět interně pracovat s reprezentací řetězců, kde jedna položka pole odpovídá jednomu znaku. Implementace, kde je jeden znak popsán více widechary, odporuje jednak specifikaci, jednak zdravému rozumu a do třetice je úplně k ničemu.
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.