Qt5: compile error while QSharedPointer<const T>::create() - qt

Is it "expected" for QSharedPointer::create() not to work or is it a bug? I get an error:
/usr/include/qt5/QtCore/qsharedpointer_impl.h:439:9: error:
invalid conversion from ‘const void*’ to ‘void*’ [-fpermissive]
new (result.data()) T(std::forward<Args>(arguments)...);
casting from nonconst shared pointer and constructor from raw const pointer work.
I got this for Qt5.7.0 and Qt5.10.0.
Here is a minimal example:
#include <QSharedPointer>
struct A {};
int main(int argc, char *argv[])
{
auto ca = QSharedPointer<const A>::create();
return 0;
}
Here is one file (not minimal) example but with few working cases, 2 not working and a debug. Commented defines are for "not compiling" parts.
#include <QSharedPointer>
#include <QDebug>
#define FROM_PTR
//#define CONST_CREATE
#define FROM_RAW_PTR
#define PERFECT_FORWARD_CREATE
//#define PERFECT_FORWARD_CREATE_CONST
#define BUILTIN_CAST
class A
{
public:
A() = default;
A(int i) : _i{i} {}
void foo() const { qDebug() << "const foo" << _i; }
void foo() { qDebug() << "foo" << ++_i; }
private:
int _i{0};
};
using ASPtr = QSharedPointer<A>;
using ASCPtr = QSharedPointer<const A>;
int main(int argc, char *argv[])
{
Q_UNUSED(argc)
Q_UNUSED(argv)
#ifdef FROM_PTR
qDebug() << "FROM_PTR";
auto a1 = ASPtr::create();
a1->foo();
auto ca1 = static_cast<ASCPtr>(a1);
ca1->foo();
qDebug() << "\n";
#endif // FROM_PTR
#ifdef CONST_CREATE
qDebug() << "CONST_CREATE";
auto ca2 = ASCPtr::create();
ca2->foo();
qDebug() << "\n";
#endif // CONST_CREATE
#ifdef FROM_RAW_PTR
qDebug() << "FROM_RAW_PTR";
auto ca3 = ASCPtr(new const A);
ca3->foo();
qDebug() << "\n";
#endif // FROM_RAW_PTR
#ifdef PERFECT_FORWARD_CREATE
qDebug() << "PERFECT_FORWARD_CREATE";
auto a2 = ASPtr::create(10);
a2->foo();
qDebug() << "\n";
#endif // PERFECT_FORWARD_CREATE
#ifdef PERFECT_FORWARD_CREATE_CONST
qDebug() << "PERFECT_FORWARD_CREATE_CONST";
auto ca4 = ASCPtr::create(20);
ca4->foo();
qDebug() << "\n";
#endif // PERFECT_FORWARD_CREATE
#ifdef BUILTIN_CAST
qDebug() << "BUILTIN_CAST";
QSharedPointer<A> a3 = ASPtr::create();
a3->foo();
auto ca4 = a3.constCast<const A>();
ca4->foo();
qDebug() << "\n";
#endif // BUILTIN_CAST
return 0;
}

That is a known Qt bug (QTBUG-49748). Although it is marked as resolved in Qt 5.6.0, the bug is still present as pointed out in the comments.
Why is this happening?
Look at the implmentation of the class QSharedPointer qsharedpointer_impl.h.
In particular the line:
new (result.data()) T(std::forward<Args>(arguments)...);
uses the result.data() as the new expression placement params. Unfortunately, one can not use a const pointer as a placement param (have a look at this question here on SO for more details).
Hence, there's not much you can do except reporting this to Qt developers via the official bug tracker.
You may have a look at the smart pointers provided by the standard library (e.g. std::shared_ptr) if you are not forced to use Qt ones.
UPDATE
As reported in Qt bug tracker, this bug was fixed in version 5.11 (here is the related commit). Basically, they used std::remove_cv to remove the topmost const from the type specified.

Related

Recommended Poco DatagramSocket Receive example doesn't compile

Using Poco-1.12.4-release and g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0, The recommended example code for DatagramSocket Receive in this doc:
https://pocoproject.org/slides/200-Network.pdf
compiles with this error:
dgs.cpp: In function ‘int main(int, char**)’:
dgs.cpp:34:33: error: no matching function for call to ‘Poco::Net::DatagramSocket::DatagramSocket(Poco::Net::SocketAddress&)’
34 | Poco::Net::DatagramSocket dgs(sa);
What happened? Is there a fix for this example?
Thanks
The code is:
// DatagramSocket receive example
#include "Poco/Net/DatagramSocket.h"
#include "Poco/Net/SocketAddress.h"
#include <iostream>
int main(int argc, char** argv)
{
Poco::Net::SocketAddress sa(Poco::Net::IPAddress(), 514);
Poco::Net::DatagramSocket dgs(sa);
char buffer[1024];
for (;;)
{
Poco::Net::SocketAddress sender;
int n = dgs.receiveFrom(buffer, sizeof(buffer)-1, sender);
buffer[n] = '\0';
std::cout << sender.toString() << ": " << buffer << std::endl;
}
return 0;
}
I tried this:
Poco::Net::SocketAddress sa(Poco::Net::IPAddress(), 514);
Poco::Net::DatagramSocket dgs(Poco::Net::SocketAddress::IPv4);
dgs.connect(sa);
It compiles, but is it correct?

#define displayed output where it shouldn't

I'm trying to manage my own Debug system on Qt but I have some issues :
main.h
#include <QCoreApplication>
#include "PhTools/PhDebug.h"
int main(int argc, char *argv[])
{
// Test of Debug tool
DEBUG << "Test";
// Test of TimeCode
for(int i=0; i<3;i++)
{
if(false)
DEBUG << "problem with me";
}
return 0;
}
PhDebug.h
#ifndef PHDEBUG_H
#define PHDEBUG_H
#include <QDebug>
#include <QDate>
#include <QRect>
#define DEBUG PhDebug d; d << PHDEBUG
#define PHDEBUG qDebug() << __FUNCTION__ << ":"
// In order to get rid of double quotes when displaying a variable
#define Q(string) (string).toStdString().c_str()
class PhDebug
{
public:
QDebug operator<<(QDebug dbg)
{
QString d;
d = QDate::currentDate().toString("dd.MM.yyyy");
d += " - ";
d += QTime::currentTime().toString("hh.mm.ss.zzz");
d += " in";
dbg << Q(d);
return dbg;
}
};
#endif // PHDEBUG_H
So the output should be 04.09.2013 - 12.30.51.513 in main : Test but instead I have this :
04.09.2013 - 12.30.51.513 in main : Test
04.09.2013 - 12.30.51.514 in main : problem with me
04.09.2013 - 12.30.51.514 in main : problem with me
04.09.2013 - 12.30.51.514 in main : problem with me
You problem is lack of braces around if(false). The d << PHDEBUG part of your macro still gets executed.
Incidentally, Qt already has a helper that does the same thing as your Q macro: qPrintable

QT QString from QDataStream

I'm working with a buffer and I'm trying to get a string from it, but isnt working...
Example:
*void myFunc(QDataStream& in)
{
quint8 v;
in >> v;
// Ok, I caught v value successfuly
QString s;
in >> s;
// Didnt work :<
}*
The string lenght is stored on 2 first bytes...
Thanks
If the string was not written as a QString, you need to read its length and content separately.
quint8 v;
in >> v;
quint16 length = 0;
in >> length;
// the string is probably utf8 or latin
QByteArray buffer(length, Qt::Uninitialized);
in.readRawData(buffer.data(), length);
QString string(buffer);
You might have to change the endianness of the QDataStream with QDataStream::setByteOrder before reading the 16-bit length.
We should really see the writing code and how you create the QDataStream. I tried with the following sample, and in this case your function works very well:
#include <QCoreApplication>
#include <QDebug>
#include <QDataStream>
#include <QBuffer>
void myFunc(QDataStream& in)
{
quint8 v;
in >> v;
qDebug() << v;
// Ok, I caught v value successfuly
QString s;
in >> s;
qDebug() << s;
// Didnt work :<
}
int main(int argc, char ** argv) {
QCoreApplication a(argc, argv);
QBuffer buffer;
buffer.open(QBuffer::ReadWrite);
// write test data into the buffer
QDataStream out(&buffer);
quint8 ival = 42;
QString sval = "Qt";
out << ival;
out << sval;
// read back data
buffer.seek(0);
myFunc(out);
return a.exec();
}
Output when executed:
$ ./App
42
"Qt"

R Eurequa interface

http://creativemachines.cornell.edu/eureqa/
http://code.google.com/p/eureqa-api/
Is there a way of interfacing Eureqa with R?
(windows os)
Perhaps:
Rcpp package and:
The simplest possible complete C++ program using the Eureqa API:
#include eureqa/eureqa.h
#include iostream
int main(int argc, char *argv[])
{
// initialize data set and options
eureqa::data_set data("my_data.txt");
eureqa::search_options options("y = f(x)");
// connect to a eureqa server
eureqa::connection conn("127.0.0.1");
conn.send_data_set(data);
conn.send_options(options);
conn.start_search();
// display results
eureqa::search_progress progress;
eureqa::solution_frontier solutions;
while (conn.query_progress(progress))
{
solutions.add(progress.solution_);
std::cout << progress.summary() << std::endl;
std::cout << solutions.to_string() << std::endl;
}
return 0;
}

Qt Problems compiling using an extern variable

I have a rellly long process that produces about 700 Mb of a txt log output file. This is very hard to manage. So I want to divide the output in multiple smaller log files. This is what my main.cpp looks like
#include <QtGui/QApplication>
#include "mineedit.h"
#include "logoutput.h"
#include <iostream>
void messageHandling(QtMsgType type, const char *msg){
if (ERRORLOGGER.isEmpty()){
ERRORLOGGER = DEFERRORLOGGER;
}
std::cout << "In Message Handling" << std::endl;
std::cout << "Writing to file" << ERRORLOGGER.toStdString() << std::endl;
QFile file(ERRORLOGGER);
file.open(QFile::Append);
QTextStream stream(&file);
switch (type) {
case QtDebugMsg:
stream << msg << "\n";
file.close();
break;
case QtWarningMsg:
stream << "WARNING: " << msg << "\n";
file.close();
break;
case QtCriticalMsg:
stream << "CRITICAL: " << msg << "\n";
file.close();
break;
case QtFatalMsg:
stream << "FATAL: " << msg << "\n";
file.close();
abort();
}
}
int main(int argc, char *argv[])
{
ERRORLOGGER = DEFERRORLOGGER;
qInstallMsgHandler(messageHandling);
QApplication a(argc, argv);
MineEdit w;
w.show();
return a.exec();
}
[/CODE]
And my logoutput.h is like
#ifndef LOGOUTPUT_H
#define LOGOUTPUT_H
#include <QString>
//----------------------------For outputting an error file------------------------------
#define DEFERRORLOGGER "/home/aarelovich/Documents/log.err"
#define FOLDER_OUTPUT_LOG "./home/aarelovich/Documents"
extern QString ERRORLOGGER;
#endif // LOGOUTPUT_H
Now in a part of my code I do:
ERRORLOGGER = name_of_current_log_file.
However I get the following compilation errors:
obj/main.o: In function messageHandling(QtMsgType, char const*)':
/home/aarelovich/Dropbox/MineSim/main.cpp:8: undefined reference toERRORLOGGER'
/home/aarelovich/Dropbox/MineSim/main.cpp:9: undefined reference to ERRORLOGGER'
/home/aarelovich/Dropbox/MineSim/main.cpp:13: undefined reference toERRORLOGGER'
/home/aarelovich/Dropbox/MineSim/main.cpp:15: undefined reference to ERRORLOGGER'
obj/main.o: In functionmain':
/home/aarelovich/Dropbox/MineSim/main.cpp:40: undefined reference to ERRORLOGGER'
obj/mineedit.o:/home/aarelovich/Dropbox/MineSim/mineedit.cpp:101: more undefined references toERRORLOGGER' follow
collect2: ld returned 1 exit status
Can anyone please tell me what am I doing wrong? Or how I can dynamically change the output file in which I create my application log?
Thanks for any help
Your problem is probably related to extern variable.
Here is an example of how to use extern keyword in c++.
Beware that C++ and C have differences with extern keyword when linking.
Basicall what you need to do is
global.cpp:
// declaration of g_nValue
int g_nValue = 5;
main.cpp:
// extern tells the compiler this variable is declared elsewhere
extern int g_nValue;
int main()
{
g_nValue = 7;
return 0;
}
In your example if you use extern QString ERRORLOGGER; in logoutput.h,
this variable needs to be declared in another cpp just as explained in the link.
I hope this helps

Resources