Cryptic warning when initializing a QList from a std::ranges::view
-
wrote on 12 Jan 2024, 12:17 last edited by Asperamanca 1 Dec 2024, 12:55
I try to initialize a QList from a std::ranges::view like this:
struct Node { public: int m_Id; //... } auto convertToIdListView(const auto& arg) { auto fConvertToId = [](const Node& node) { return node.m_Id; }; auto idListView = std::views::transform(arg,fConvertToId); return idListView; } QList<int> convertToIdList(const QList<Node>& arg) { auto idListView = convertToIdListView(arg); return {QList<int>{idListView.begin(), idListView.end()}}; }
And (on MSVC 2022) get the warning:
warning: C4996: 'QList<Node>::const_iterator::operator T': Use operator* or operator-> rather than relying on the implicit conversion between a QList/QVector::const_iterator and a raw pointer
What does this mean?
Is it dangerous to do this?
How to properly initialize QList from a std::ranges::view? -
I try to initialize a QList from a std::ranges::view like this:
struct Node { public: int m_Id; //... } auto convertToIdListView(const auto& arg) { auto fConvertToId = [](const Node& node) { return node.m_Id; }; auto idListView = std::views::transform(arg,fConvertToId); return idListView; } QList<int> convertToIdList(const QList<Node>& arg) { auto idListView = convertToIdListView(arg); return {QList<int>{idListView.begin(), idListView.end()}}; }
And (on MSVC 2022) get the warning:
warning: C4996: 'QList<Node>::const_iterator::operator T': Use operator* or operator-> rather than relying on the implicit conversion between a QList/QVector::const_iterator and a raw pointer
What does this mean?
Is it dangerous to do this?
How to properly initialize QList from a std::ranges::view?{QList<Node>{idListView.begin(), idListView.end()}};
Why do you convert a QList<Node> to a QList<int>, then back to a QList<Node> and a QList<int> ? Does this even compile? Please provide a minimal, compilable example of your code. Also which Qt and MSVC version do you use?
And you want idListView to be const.
-
{QList<Node>{idListView.begin(), idListView.end()}};
Why do you convert a QList<Node> to a QList<int>, then back to a QList<Node> and a QList<int> ? Does this even compile? Please provide a minimal, compilable example of your code. Also which Qt and MSVC version do you use?
And you want idListView to be const.
wrote on 12 Jan 2024, 13:01 last edited by@Christian-Ehrlicher Sorry for the confusion. Fixed return statement of last function (convertToIdList).
Here is the complete example:
#include <ranges> #include <QDebug> struct Node { public: int m_Id; //... }; auto convertToIdListView(const auto& arg) { auto fConvertToId = [](const Node& node) { return node.m_Id; }; auto idListView = std::views::transform(arg,fConvertToId); return idListView; } QList<int> convertToIdList(const QList<Node>& arg) { const auto idListView = convertToIdListView(arg); return {QList<int>{idListView.begin(), idListView.end()}}; } int main(int argc, char *argv[]) { QList<Node> nodeList{{.m_Id=1},{.m_Id=2},{.m_Id=5}}; qDebug() << convertToIdList(nodeList); }
-
@Christian-Ehrlicher Sorry for the confusion. Fixed return statement of last function (convertToIdList).
Here is the complete example:
#include <ranges> #include <QDebug> struct Node { public: int m_Id; //... }; auto convertToIdListView(const auto& arg) { auto fConvertToId = [](const Node& node) { return node.m_Id; }; auto idListView = std::views::transform(arg,fConvertToId); return idListView; } QList<int> convertToIdList(const QList<Node>& arg) { const auto idListView = convertToIdListView(arg); return {QList<int>{idListView.begin(), idListView.end()}}; } int main(int argc, char *argv[]) { QList<Node> nodeList{{.m_Id=1},{.m_Id=2},{.m_Id=5}}; qDebug() << convertToIdList(nodeList); }
wrote on 12 Jan 2024, 13:02 last edited by@Asperamanca Oh, and I use Qt 6.5.2 and MSVC 17.4 with project set to use C++20
-
@Asperamanca Oh, and I use Qt 6.5.2 and MSVC 17.4 with project set to use C++20
This also happens with Qt6.8 but can't find out what's the exact reason - you should create a bug report.
But why a view at all? This works with less code also with c++11.
QList<int> convertToIdList(const QList<Node>& arg) { QList<int> ret; ret.reserve(arg.size()); std::transform(arg.begin(), arg.end(), std::back_inserter(ret), [](const Node &node)->int { node.m_Id; }); return ret;
-
This also happens with Qt6.8 but can't find out what's the exact reason - you should create a bug report.
But why a view at all? This works with less code also with c++11.
QList<int> convertToIdList(const QList<Node>& arg) { QList<int> ret; ret.reserve(arg.size()); std::transform(arg.begin(), arg.end(), std::back_inserter(ret), [](const Node &node)->int { node.m_Id; }); return ret;
wrote on 12 Jan 2024, 14:56 last edited by Asperamanca 1 Dec 2024, 15:06@Christian-Ehrlicher
My approach allows me to convert any iterable container - List, Set, std::vector, range,...
Also, using ranges and views makes the code nicer if you have multiple steps.EDIT: Ok, on the first point, it would be trivial to change your code to also work for any types that have begin() and end()
But in general, I'd like to use ranges more for more complex tasks, and translating back and forth between ranges, views and Qt containers (which often are use in the APIs in my codebase) is difficult. -
@Christian-Ehrlicher
My approach allows me to convert any iterable container - List, Set, std::vector, range,...
Also, using ranges and views makes the code nicer if you have multiple steps.EDIT: Ok, on the first point, it would be trivial to change your code to also work for any types that have begin() and end()
But in general, I'd like to use ranges more for more complex tasks, and translating back and forth between ranges, views and Qt containers (which often are use in the APIs in my codebase) is difficult.wrote on 15 Jan 2024, 08:13 last edited by@Asperamanca See bug report https://bugreports.qt.io/browse/QTBUG-120924
-
1/7