How to convert a std::string_view to a QStringView - c++

I tried the following conversions, but all give me a no matching constructor for initialization of 'QStringView' error (comments reflect the constructor I was trying to call):
string someString = "hello world";
string_view strView( someString );
// QStringView(const Char (&)[N] string = N) or
// QStringView(const Char *str, qsizetype len)
QStringView qStrView1(strView.data(), strView.size());
// QStringView(const Char *first, const Char *last)
QStringView qStrView2(strView.data(), strView.data() + strView.size());
// QStringView(const Char *first, const Char *last)
QStringView qStrView3(strView.begin(), strView.end());
QStringView qStrView3a(strView.cbegin(), strView.cend());
// QStringView(const Char *str)
QStringView qStrView4(strView.data());
(I thought the 1st or 2nd conversion might work, and tried the 3rd and 4th just out of disappointment.)
Can someone please point me to the right conversion? Do I miss something?
Or do I need to dublicate all std::strings as QStrings and create QStringViews from these, by reusing the begin/end positions?
( Besides that, I did not now figure out, how to insert a QStringView into a QTableWidgetItem. I would appreciate any help on this problem as well. )
Context
I read out file content as std::string and split it into lines of fields based on separators. In order to do this efficiently, I generated a std::vector of std::string_view to store the fields. Now I want to visualize the strings in a Qt GUI (actually aiming at QTableWidgetItems) and thought QStringView might serve me well for the GUI part. I want to keep BusinessLogic independent of the GUI an therefore avoided any includes of Qt libraries there.
Setting
Qt 5.15.0
CONFIG += c++17
MSVC2019 amd64
Windows 10
Errors
(I removed note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided, note: candidate constructor template not viable: requires single argument 'str', but 2 arguments were provided and alike)
qStrView1:
qstringview.h:173:22: note: candidate template ignored: requirement 'QtPrivate::IsCompatibleCharType<char>::value' was not satisfied [with Char = char]
qstringview.h:178:22: note: candidate template ignored: could not match 'const Char *' against 'std::basic_string_view::size_type' (aka 'unsigned long long')
qstringview.h:191:22: note: candidate template ignored: requirement 'QtPrivate::IsCompatibleArray<const char *>::value' was not satisfied [with Array = const char *]
qStrView2:
qstringview.h:173:22: note: candidate template ignored: requirement 'QtPrivate::IsCompatibleCharType<char>::value' was not satisfied [with Char = char]
qstringview.h:178:22: note: candidate template ignored: requirement 'QtPrivate::IsCompatibleCharType<char>::value' was not satisfied [with Char = char]
qstringview.h:191:22: note: candidate template ignored: requirement 'QtPrivate::IsCompatibleArray<const char *>::value' was not satisfied [with Array = const char *]
qStrView3:
qstringview.h:173:22: note: candidate template ignored: could not match 'const Char *' against 'std::basic_string_view<char, std::char_traits<char> >::const_iterator' (aka '_String_view_iterator<std::char_traits<char> >')
qstringview.h:178:22: note: candidate template ignored: could not match 'const Char *' against 'std::basic_string_view<char, std::char_traits<char> >::const_iterator' (aka '_String_view_iterator<std::char_traits<char> >')
qstringview.h:191:22: note: candidate template ignored: requirement 'QtPrivate::IsCompatibleArray<std::_String_view_iterator<std::char_traits<char> > >::value' was not satisfied [with Array = std::_String_view_iterator<std::char_traits<char> >]
qStrView3a:
qstringview.h:173:22: note: candidate template ignored: could not match 'const Char *' against 'std::basic_string_view<char, std::char_traits<char> >::const_iterator' (aka '_String_view_iterator<std::char_traits<char> >')
qstringview.h:178:22: note: candidate template ignored: could not match 'const Char *' against 'std::basic_string_view<char, std::char_traits<char> >::const_iterator' (aka '_String_view_iterator<std::char_traits<char> >')
qstringview.h:191:22: note: candidate template ignored: requirement 'QtPrivate::IsCompatibleArray<std::_String_view_iterator<std::char_traits<char> > >::value' was not satisfied [with Array = std::_String_view_iterator<std::char_traits<char> >]
qStrView4:
qstringview.h:103:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'std::basic_string_view<char, std::char_traits<char> >::const_pointer' (aka 'const char *') to 'const QStringView' for 1st argument
qstringview.h:103:7: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'std::basic_string_view<char, std::char_traits<char> >::const_pointer' (aka 'const char *') to 'QStringView' for 1st argument
qstringview.h:169:22: note: candidate constructor not viable: no known conversion from 'std::basic_string_view<char, std::char_traits<char> >::const_pointer' (aka 'const char *') to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
qstringview.h:196:22: note: candidate template ignored: requirement 'QtPrivate::IsCompatibleArray<const char *>::value' was not satisfied [with Array = const char *]
qstringview.h:200:22: note: candidate template ignored: requirement 'QtPrivate::IsCompatiblePointer<const char *>::value' was not satisfied [with Pointer = const char *]
qstringview.h:209:5: note: candidate template ignored: requirement 'std::is_same<const char *, QString>::value || std::is_same<const char *, QStringRef>::value' was not satisfied [with String = const char *]
qstringview.h:214:22: note: candidate template ignored: requirement 'QtPrivate::IsCompatibleStdBasicString<const char *>::value' was not satisfied [with StdBasicString = const char *]

Thanks for pointing me towards std::wstring. It took me a while understand the wchar_t , wstring, wcout, wifstream, ... stuff, but finally I have the following code working:
Note: still requires CONFIG += 17 in .pro file and following includes
#include <QStringView>
#include <string_view>
#include <string>
// create wstring and convert to QStringView
wstring somewstring = L"abc -ä-ö-ü-ß-"; //!< example string
wstring_view wview(somewstring);
// either work:
QStringView qstrv2a(wview.data(), wview.size());
QStringView qstrv2b(wview.data(), wview.data() + wview.size());
where either of the above constructors works fine.
Example using QStringView inside a QLabel
// setup minimum GUI
QWidget* mainWidget = new QWidget(this);
setCentralWidget(mainWidget);
QVBoxLayout* mainLayout = new QVBoxLayout;
mainWidget->setLayout(mainLayout);
// create wstring and convert to QStringView
wstring somewstring = L"abc -ä-ö-ü-ß-"; //!< example string
wstring_view wview(somewstring);
// either work:
QStringView qstrv1(wview.data(), wview.size());
// convert to label
QLabel* otherLabel = new QLabel(qstrv1.toLocal8Bit());
mainLayout->addWidget(otherLabel);
Example from file to QLabel
// additinonal standard libararies:
#include <fstream>
#include <sstream>
// setup minimum GUI
QWidget* mainWidget = new QWidget(this);
setCentralWidget(mainWidget);
QVBoxLayout* mainLayout = new QVBoxLayout;
mainWidget->setLayout(mainLayout);
// read file with UTF-8 characters (to a std::string)
std::string tempFileContent;
ifstream file("./infile.txt", ios::binary);
file.seekg(0, file.end);
tempFileContent.resize(file.tellg());
file.seekg(0, file.beg);
file.read(&tempFileContent[0], tempFileContent.size());
file.close();
// convert std::string -> std::wstring
std::wstringstream wss;
wss << tempFileContent.c_str();
std::wstring fileContent = wss.str();
// convert std::wstring -> QStringView
// - either work:
QStringView qstrv2(fileContent.data(), fileContent.size());
// convert to label
QLabel* someLabel = new QLabel(qstrv2.toLatin1()); //!< WORKS
mainLayout->addWidget(someLabel);
/* these did not work:
// total garbage
QLabel(QString::fromUtf8(qstrv2.toString().toStdString().c_str()));
// misses just the 'ß'
QLabel* someLabel = new QLabel(qstrv2.toLocal8Bit());
*/
where file content was
a-b-c-ä-ö-ü-ß-0-1-2
interestingly reading a text file with wifstream to a wstring takes much longer than converting a read string to a wstring using wstringstream. (which is still much slower than reading to std::string itself)

Related

using the correct to_chars overload

I'm using Clang 14 (on Apple M1), which has full support for C++ 17, and I'm trying to utilize the new to_chars function. Here's my very simple test file:
#include <charconv>
#include <iostream>
int main() {
char a[10];
double pi = 3.141592;
std::to_chars_result res = std::to_chars(a, a+10, pi);
*res.ptr = '\0';
std::cout << a << std::endl;
}
My compile command is clang -std=c++17 test_to_chars.cpp, and the output is below:
test_to_chars.cpp:8:30: error: call to deleted function 'to_chars'
std::to_chars_result res = std::to_chars(a, a+10, pi);
^~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1/charconv:166:6: note: candidate function has been explicitly deleted
void to_chars(char*, char*, bool, int = 10) = delete;
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1/charconv:450:1: note: candidate template ignored: requirement 'is_integral<double>::value' was not satisfied [with _Tp = double]
to_chars(char* __first, char* __last, _Tp __value)
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1/charconv:458:1: note: candidate function template not viable: requires 4 arguments, but 3 were provided
to_chars(char* __first, char* __last, _Tp __value, int __base)
^
test_to_chars.cpp:8:24: error: no viable conversion from 'void' to 'std::to_chars_result'
std::to_chars_result res = std::to_chars(a, a+10, pi);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1/charconv:154:25: note: candidate constructor (the implicit copy constructor) not viable: cannot convert argument of incomplete type 'void' to 'const std::to_chars_result &' for 1st argument
struct _LIBCPP_TYPE_VIS to_chars_result
^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1/charconv:154:25: note: candidate constructor (the implicit move constructor) not viable: cannot convert argument of incomplete type 'void' to 'std::to_chars_result &&' for 1st argument
2 errors generated.
I'm calling to_chars(char*, char*, double) but for some reason it's using an implicit conversion and trying to call to_chars(char*, char*, bool, int = 10) instead, which is a deleted function.
Is there a way for me to tell C++ that I don't want it to convert my double parameter to a bool?
I'm using Clang 14 (on Apple M1), which has full support for C++ 17
This is unfortunately not correct. While the compiler itself has full C++17 support, the stdlib of your clang version (Apple clang 14) does not implement any floating point charconv features.
See the entry "Elementary string conversions" in the cppreference table.
It is important to note that you are not running "clang 14", but "Apple clang 14". Your code snippet compiles just fine on normal clang 14.

Convert DWORD to String with c++

I get Idmachine with GetVolumeInformation command. I want changed idmachine (DWORD) to string then show in TEdit(C++ builder) but not. Please help me!
GetVolumeInformation(L"C:\\",NULL,NULL,&dwVolSerial,NULL,NULL,NULL,NULL);
std::wstring wstr = std::to_wstring(idmachine);
std::string str = std::string(wstr.begin(), wstr.end());
ShowMessage(str);
Error
Vcl.Dialogs.hpp(1430): candidate function not viable: no known conversion from 'std::string' (aka 'basic_string, allocator >') to 'const System::UnicodeString' for 1st argument

String c++ manipulation

Why the following code have compilation error?
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str="abc";
string result=str[0];
cout<<result<<endl;
return 0;
}
However, the following code works fine:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str="abc";
str=str[0];
cout<<str<<endl;
return 0;
}
I works in unix and compilation command is: "g++ -g test.cpp -std=c++11 -o a", thenm ./a
The error for the first test.cpp after compile is:
test.cpp:9:21: error: invalid conversion from 'char' to 'const char*' [-fpermissive]
string result=str[0];
^
In file included from /usr/um/gcc-4.8.2/include/c++/4.8.2/string:52:0,
from /usr/um/gcc-4.8.2/include/c++/4.8.2/bits/locale_classes.h:40,
from /usr/um/gcc-4.8.2/include/c++/4.8.2/bits/ios_base.h:41,
from /usr/um/gcc-4.8.2/include/c++/4.8.2/ios:42,
from /usr/um/gcc-4.8.2/include/c++/4.8.2/ostream:38,
from /usr/um/gcc-4.8.2/include/c++/4.8.2/iostream:39,
from test.cpp:1:
/usr/um/gcc-4.8.2/include/c++/4.8.2/bits/basic_string.h:490:7: error: initializing argument 1 of 'std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]' [-fpermissive]
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
^
std::basic_string doesn't have any constructor that takes a single CharT argument. This means that std::string (i.e. std::basic_string<char>) cannot be constructed from a single char.
The class does, however, have an assignment operator overload that takes a single CharT argument, which is why your second example compiles.
The difference between the two cases is because in the first you're performing copy initialization, which means technically you're first attempting to construct a temporary std::string instance from the char argument, and then copy it over to result. In the second you're performing assignment, which means assigning a new value to an existing std::string instance.
basic_string does have a constructor that takes a count followed by a character:
basic_string(size_type count, CharT ch, const Allocator& alloc = Allocator());
so your original example would compile if you changed the offending line to
string result = {1, str[0]};
The following code works fine as well:
string result;
result=str[0];
That means the difference is between initialization and simple assignment and, if you examine the error:
error: invalid conversion from ‘char’ to ‘const char*’
it should be clear that the initialization is not as "full-featured" as assignment - the is no string constructor that takes a char argument (there is an assignment that takes a char which is why your second example works).
You can fix it (in one way, there's no doubt others as well) by ensuring you initialize with a string rather than a character:
string result = str.substr(0,1);
str[0] returns a char&, but there is no conversion from char& to std::string
try thins instead
string result = string(1, str[0]);

Compile header file and two .cpp files in Unix/Linux (Ubuntu)

I am trying to compile 3 files total and can not get it to. The code works in visual++. I have uploaded all 3 files in the same dir and used the following command.
g++ -o edit Album.cpp lab8.cpp
My file names are listed below
Album.cpp
Album.h
lab8.cpp
Note the code was written in visual studio C++ and compiled just fine there.
Results in the following
lab8.cpp: In function ‘std::vector read_album_file(std::string)’:
lab8.cpp:142:25: error: no matching function for call to ‘std::basic_ifstream::basic_ifstream(std::string&)’
ifstream read (filename);// the ifstream is used to read from the file
^
lab8.cpp:142:25: note: candidates are:
In file included from lab8.cpp:38:0:
/usr/include/c++/4.8/fstream:467:7: note: std::basic_ifstream<_CharT, _Traits>::basic_ifstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits; std::ios_base::openmode = std::_Ios_Openmode]
basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
^
/usr/include/c++/4.8/fstream:467:7: note: no known conversion for argument 1 from ‘std::string {aka std::basic_string}’ to ‘const char*’
/usr/include/c++/4.8/fstream:453:7: note: std::basic_ifstream<_CharT, _Traits>::basic_ifstream() [with _CharT = char; _Traits = std::char_traits]
basic_ifstream() : __istream_type(), _M_filebuf()
^
/usr/include/c++/4.8/fstream:453:7: note: candidate expects 0 arguments, 1 provided
/usr/include/c++/4.8/fstream:427:11: note: std::basic_ifstream::basic_ifstream(const std::basic_ifstream&)
class basic_ifstream : public basic_istream<_CharT, _Traits>
^
/usr/include/c++/4.8/fstream:427:11: note: no known conversion for argument 1 from ‘std::string {aka std::basic_string}’ to ‘const std::basic_ifstream&’
Look at the constructor prototype of ifstream. It takes a const char * and a optional argument, soyou need to write filename.c_str()

Qt - getting the current date in mmmm YYYY format (as a string)

I'm trying to retrieve the current date as a string in mmmm YYYY format with QDate. However, I can't pass QDate::currentDate with an argument. Another problem is the fact that the function argument I am passing this in is QString, meaning that g++ throws conversion errors. How can get around this?
Here the code at the moment:
QDate date = QDate::currentDate();
Core::MessageUser(this->CurrentEdit->User, warning, QString::number(date),
title, true, dependency);
The compiler error I am constantly getting whatever I do is this:
mainwindow.cpp: In member function 'bool Huggle::MainWindow::Warn(QString, Huggle::RevertQuery*)':
mainwindow.cpp:463:77: error: no matching function for call to 'QString::number(QDate&)'
Core::MessageUser(this->CurrentEdit->User, warning, QString::number(date),
^
mainwindow.cpp:463:77: note: candidates are:
In file included from /usr/include/qt5/QtCore/qobject.h:48:0,
from /usr/include/qt5/QtWidgets/qwidget.h:46,
from /usr/include/qt5/QtWidgets/qmainwindow.h:45,
from /usr/include/qt5/QtWidgets/QMainWindow:1,
from mainwindow.h:14,
from mainwindow.cpp:11:
/usr/include/qt5/QtCore/qstring.h:556:20: note: static QString QString::number(int, int)
static QString number(int, int base=10);
^
/usr/include/qt5/QtCore/qstring.h:556:20: note: no known conversion for argument 1 from 'QDate' to 'int'
/usr/include/qt5/QtCore/qstring.h:557:20: note: static QString QString::number(uint, int)
static QString number(uint, int base=10);
^
/usr/include/qt5/QtCore/qstring.h:557:20: note: no known conversion for argument 1 from 'QDate' to 'uint {aka unsigned int}'
/usr/include/qt5/QtCore/qstring.h:558:20: note: static QString QString::number(long int, int)
static QString number(long, int base=10);
^
/usr/include/qt5/QtCore/qstring.h:558:20: note: no known conversion for argument 1 from 'QDate' to 'long int'
/usr/include/qt5/QtCore/qstring.h:559:20: note: static QString QString::number(ulong, int)
static QString number(ulong, int base=10);
^
/usr/include/qt5/QtCore/qstring.h:559:20: note: no known conversion for argument 1 from 'QDate' to 'ulong {aka long unsigned int}'
/usr/include/qt5/QtCore/qstring.h:560:20: note: static QString QString::number(qlonglong, int)
static QString number(qlonglong, int base=10);
^
/usr/include/qt5/QtCore/qstring.h:560:20: note: no known conversion for argument 1 from 'QDate' to 'qlonglong {aka long long int}'
/usr/include/qt5/QtCore/qstring.h:561:20: note: static QString QString::number(qulonglong, int)
static QString number(qulonglong, int base=10);
^
/usr/include/qt5/QtCore/qstring.h:561:20: note: no known conversion for argument 1 from 'QDate' to 'qulonglong {aka long long unsigned int}'
/usr/include/qt5/QtCore/qstring.h:562:20: note: static QString QString::number(double, char, int)
static QString number(double, char f='g', int prec=6);
^
/usr/include/qt5/QtCore/qstring.h:562:20: note: no known conversion for argument 1 from 'QDate' to 'double'
make: *** [mainwindow.o] Error 1
I think you need to call:
Core::MessageUser(this->CurrentEdit->User, warning, date.toString(),
title, true, dependency);
instead
UPDATE
If you need to print out only the year value:
Core::MessageUser(this->CurrentEdit->User, warning, QString::number(date.year()),
title, true, dependency);