Workaround for ambiguous call to overloaded function - c++

void printOutput(std::string text);
void printOutput(std::string& text);
Both functions print some text out to the console, but I wanted to handle each case where:
std::string testOutput = "asdf";
output->printOutput(testOutput); // Gives the error as it can use either function
In some cases I may want to:
output->printOutput("asdf"); // Only the first function can be used
Rather new to all this, is there a way I can handle this?

Pass by const reference:
void printOutput(const std::string &text);
Both forms can bind to that, and you shouldn't have to modify what you print.

Unless you're planning to modify the string passed in by reference, a single
void printOutput(std::string const& text);
will work.
Or are you hoping to do something different in each version?

Related

How to ignore the first action in the gtest DoAll()

I declare a function
void MyFunction(const std::wstring& inParameter, std::wstring& outParamater);
The first parameter is a passed in parameter, the second one is the value out parameter, the value I want to get by the function will pass it out by outParameter.
Now I Gmock it
MOCK_METHOD2(MyFunction, void(const std::wstring&, std::wstring&));
However, when I use this mock function:
std::wstring firstStr = L"firstStr";
std::wstring test = L"test";
EXPECT_CALL(*myGmockInstance, MyFunction(firstStr, _)).Times(1).WillOnce(DoAll(firstStr, SetArgReferee<1>(test)));
It doesn't work.
I also tried
EXPECT_CALL(*myGmockInstance, MyFunction(_, _)).Times(1).WillOnce(DoAll(_, SetArgReferee<1>(test)));
or
EXPECT_CALL(*myGmockInstance, MyFunction(_, _)).Times(1).WillOnce(DoAll(firstStr, SetArgReferee<1>(test)));
or
EXPECT_CALL(*myGmockInstance, MyFunction(_, _)).Times(1).WillOnce(DoAll(SetArgReferee<0>(firstStr), SetArgReferee<1>(test)));
I understand that the inParameter is const, so I cannot use SetArgReferee for it. But how to set its value and at the same time I can set value for outParameter?
I think that the title of your question is quite misleading. From what I understand, you just want to assign some arbitrary value to your function's second argument (the output argument). This is how you can do it using Invoke:
using ::testing::_;
void assignStringToArg(const std::wstring&, std::wstring& outputStr,
const std::wstring expectedStr) {
outputStr = expectedStr;
}
class SomeMock {
public:
MOCK_METHOD2(MyFunction, void(const std::wstring&, std::wstring&));
};
TEST(xxx, yyy) {
SomeMock someMock;
std::wstring firstStr(L"aaabbbccc");
std::wstring secondStr(L"I should change upon MyFunction call ...");
std::wstring expectedSecondStr(L"xxxyyyzzz");
EXPECT_CALL(someMock, MyFunction(firstStr, _)).Times(1).WillOnce(Invoke(std::bind(
&assignStringToArg,
std::placeholders::_1,
std::placeholders::_2,
expectedSecondStr)));
someMock.MyFunction(firstStr, secondStr);
ASSERT_EQ(expectedSecondStr, secondStr);
}
Note that the function provided to Invoke must have the same signature as the function that you expect to be called (that's why I use bind). You can achieve the same result using google macro ACTION_P. I prefer to use Invoke only because it looks more clean to me.
Since your case is rather simple, you can also do it using SetArgReferee like you tried before:
EXPECT_CALL(someMock, MyFunction(firstStr, _)).Times(1).WillOnce(
SetArgReferee<1>(L"something"));
someMock.MyFunction(firstStr, secondStr);
ASSERT_EQ(L"something", secondStr);
I just see no point using DoAll if you only want to do one action. But ... if you really insist:
EXPECT_CALL(someMock, MyFunction(firstStr, _)).Times(1).WillOnce(
DoAll(SetArgReferee<1>(L"something1"), SetArgReferee<1>(L"something2")));
someMock.MyFunction(firstStr, secondStr);
ASSERT_EQ(L"something2", secondStr);
It is rather stupid example, because it set's the output variable to L"something1" and then immediately to L"something2".

not able to return QString from c++ function to PERL function by using SWIG

I have c++ code (Includes Qt also), i want to call those functions by using Perl.
Which we can do by using SWIG, so I have implemented interfaces and did all the stuff need to use them in Perl script.
I have a function in c++ which returns a QString value,
QString get_string()
{
return QString("mystring");
}
I have written one more class which will be used in perl script where i have a function which calls this get_string() function and returns const char*.
const char* get_const_string()
{
QString str = get_string();
**//here I print str and str .toLocal8Bit().constData()
//both are printing the text which i shoud get here**
return str.toLocal8Bit().constData();
//here I have tried diff combinations also, as
// return str.toStdString().c_str();
}
The problem is, in get_const_string() function, I could get the string I wanted, but when I call this function in my perl script, I am getting undefine value i.e null string
.
Any idea, what is the problem here ??
I am using perl5, Qt4.8.4
Thanks in advance.
if you cant use a QString return value, maybe you can use std::string.
if both fail and you do not have limitations, you could do some dirty trick:
QString get_string()
{
static QByteArray arr;
QString str = getString();
arr = str.toLocal8Bit();
return arr.constData();
}
note that the arr variable will not be free'd untill your app is running
edit: found a possible solution to just use std::string ... string arguments are not recognized by SWIG

How can I ensure that correct function is called in case there are multiple candidates

In C++ is perfectly legitimate to do:
bool x = "hi";
Because "hi" is translated by compiler to a char array and returns a pointer to that array, which is a number and number can be implicitly converted to bool (0 is false, anything else is true).
So I have these ctor:
Exception(QString Text, bool __IsRecoverable = true);
Exception(QString Text, QString _Source, bool __IsRecoverable = true);
Sadly I figured out that calling
Exception *e = new Exception("error happened", "main.cpp #test");
It creates a new instance of "Exception" class which is created using Exception(QString Text, bool __IsRecoverable = true); constructor, which is wrong to a point.
Is there a simple way to ensure that correct function is called, other than restructuring the constructors entirely, changing position of arguments, etc?
Firstly, I'm not sure why you're dynamically allocating an exception class. I'm not sure that's ever a good idea.
You can explicitly construct a QString:
Exception e("error happened", QString("main.cpp #test"));
Or you can pass the third argument:
Exception e("error happened", "main.cpp #test", true);
Or you can add an additional constructor that takes const char* and will be preferred over the conversion to bool:
Exception(QString Text, const char* Source, bool IsRecoverable = true);
You can easily make this forward to the QString version. Also note that names beginning with an underscore and a capital letter or with two underscores are reserved.
My suggestion would be to not use default arguments. They contribute to overload resolution problems like this, and anyway it is not very readable to just see true as an argument. Whoever's reading the code then has to stop and go look up what the true means. Even if it's yourself you may forget it in a few months time when you come back to the code, especially if you do this sort of thing a lot.
For example:
struct Exception: public whatever
{
Exception(char const *text);
Exception(char const *text, char const *source);
};
struct RecoverableException: public Exception
{
RecoverableException(char const *text);
RecoverableException(char const *text, char const *source);
};
It's a little bit more typing in this source file but the payoff is that your code which actually uses the exceptions is simpler and clearer.
To implement these constructors you could have them all call a particular function in the .cpp file with relevant arguments selecting which behaviour you want.
I have a preference for using char const * rather than QString as I am paranoid about two things:
unwanted conversions
memory allocation failure
If constructing a QString throws then things go downhill fast. But you may choose to not worry about this possibility because if the system ran out of memory and your exception handling doesn't prepare for that possibility then it's going to terminate either way.

Qt 5: const char * QString cast

In Qt 4 it is possible to automatically cast a QString to a "const char *", e.g. I could pass a QString to a function that expected a "const char *".
void myFunction(const char *parameter);
QString myString;
myFunction(myString); //works in QT4
In Qt 5 I would however get an "error C2440: 'type cast' : cannot convert from 'QString' to 'const char *'" (that is the Visual C++ 2008 compiler, other compilers would throw something similar). If I understand the documentation correctly, it is because the Qt 3 compatibility layer is not included anymore in QT5.
Of course, I could change the function call from
myFunction(myString);
to
myFunction(myString.toLatin1().data());
However, I have a huge code base that compiles fine with Qt 4 and I would really like to have my old code compile with Qt 5 without modifying it. Is there any way to achieve this?
You could create a macro or inline function for your purpose to minimize the changes, but since that would also require a grep alike operation, there is not much difference.
#define QString2charp(myString) myString.toLatin1().data()
or
inline char* QString2charp (const QString &myString)
{
return myString.toLatin1().data();
}
and then:
myFunction(QString2charp(myString));
BUT
of course, in an ideal world, it would be nice if your "myFunction" could get an overload expecting a QString argument.
void myFunction(const char *parameter);
void myFunction(QString parameter);
and then the overload would be implemented like this:
void myFunction(const QString &parameter)
{
myFunction(myString.toLatin1().data());
}
of course, this would require the constructor being explicit so that no implicit conversion can happen, otherwise the compiler will complain about ambiguity in presence of both when trying to pass const char*, but if you always use QString, it should just work with Qt 5.
This is somewhat equal to rewriting the original function to a different signature expecting QString though because unfortunately the corresponding constructor is not explicit. I imagine that was not changed in Qt 5 for compatibility as it would have broken too much code.
As you can see, you do not need to change anything in your code this way, other than adding a one-liner overload. It is neat, isn't it?
You could either
Change the signature of your function to MyFunction( const QString & parameter ) (of course that works only if you don't need the one that takes char * any more)
Overload MyFunction:
void myFunction(const char *parameter); //this is your normal function
void myFunction( const QString & parameter )
{
char * c_str = nullptr;
<convert parameter to char * in any way that suits you>
myFunction( c_str );
}
If the above is impossible for some reason, the best approach is probably to write a similar wrapper:
void MyFunctionWrapper( const QString & parameter )
{
<same as above>
}
It is no longer possible to cast QString to const char* in >= Qt 5, because QString is UTF-16 and no longer has an entry for caching the result of converting to ASCII.
The way to achieve your aim is
a) Add overloads to the functions expecting const char* which can handle QStrings,
b) Add the explicit conversion code to the call-site, or
c) Go to some char-based string, like std::string.
None of those fulfill your aim of nearly no changes though.
I found this on QT forum
const QByteArray byteArray = mytext = textBox.text().toUtf8();
const char *mytext = byteArray.constData();
This resolved my issue

how to implement the macros SIGNAL and SLOT as functions QT

Well, what i want is to implement functions that works like the macros SIGNAL and SLOT but with my own implementation, so the goal is that the function (or my own macro if i can create it) receive a parameter like an String "mycustomsignal" and he return a const char* "2mycustomsignal(double,int)" so i do that using a QMap for store this asociation QMap<"signal name","signal signature">, i fill it in another function.
in this case my QMap is this->signals so i search the signature "mycustomsignal(something)" with the key "mycustomsignal" and prepend the code that QObject::connect recognize for signals and i get "2mycustomsignal(something)" so i convert it in const char* because QObject::connect have this parameters in this format and i want to use also in conjuntion with SIGNAL and SLOT MACROS like this:
QObject::connect(customwidget, customwidget->getSignal("somesignal"),
somewidget, SLOT(someslot()));
the function that i use is (only for undertand what i do):
const char* SomeClass::getSignal(QString signalName) {
QString signalsignature = this->signals.value(signalName);
signalsignature.prepend(QString::number(QSIGNAL_CODE));
QByteArray ba = signalsignature.toLatin1();
return signalformated; //Here is the lost of data because QByteArray only exist in the function
}
but this return a pointer to local and the source of the data is destroyed when the function ends, so how i could do this with a function or creating my own MACRO?
Thanks for any help or suggestion.
You have to return QByteArray from your method, return ba;, then get the const char* from the return value:
QObject::connect(customwidget, customwidget->getSignal("somesignal").constData(),
somewidget, SLOT(someslot()));
If you really want to return char pointer, then you have to keep the QByteArray around, for example by adding it to a QList member variable of the same object, so it will get destructed when the instance gets destructed.