I use this code without any error
QStandardItem *newRow;
newRow = new QStandardItem(hostname);
model2->setItem(index, 2, newRow);
I want to change the above code to the below:
QScopedPointer<QStandardItem> newRow(new QStandardItem);
model2->setItem(index, 2, newRow);
But I get this error:
C:\...\mainwindow.cpp:352: error: C2664: 'void QStandardItemModel::setItem(int,int,QStandardItem *)' : cannot convert parameter 3 from 'QScopedPointer<T>' to 'QStandardItem *'
with
[
T=QStandardItem
]
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
How can I solve the problem?
Try this, use take() method to get the pointer.
On my computer
QStandardItem *item2 = new QStandardItem("foo");
model->setItem(4,0,item2);//works
QScopedPointer<QStandardItem> newRow(new QStandardItem("foo"));
model->setItem(4,0,newRow.take());//works too
Instead of QScopedPointer<T>::take() which releases the stored pointer of the scoped pointer container i suggest to use QScopedPointer<T>::data() which returns a the pointer but does not reset the scoped pointer
But on the other hand, why would you like to use QScopedPointer to store a pointer to the QStandardItem when the model will take ownership of it and will handle its lifetime?
Related
I have a php script which was written on php 5.6.19, works on 5.3 version to, with some installed addons.
I decide to try execute it on php7.
The special of the script that I am initializing a class with parameter by reference via creating a new instance with Reflection::class. And there warning then waited variable by reference but value received.
Definition of the class' constructor method tried to create an instance from:
public function __construct($user, IDatabase &$repository, $errors = null);
Sample of code where this constructor is used:
// define manager type to create (all managers has the same constructor)
$manager = $managersNamespace . ucfirst($this->_manager) . "Manager";
// trying to create the manager
// !!!And here a Warning occurs
$reflect = new \ReflectionClass($manager);
$manager = $reflect->newInstance($user, $database, $errors);
After these I am invoking a method I need, and here the fatal error with stopped the script:
$method = "show" . ucfirst($this->_page) . "Page";
$reflect->getMethod($method)->invoke($manager);
I didn't see any changes in documentation. Anyone had the same issue?
First and foremost, why are you passing an object by reference !?
Objects have pass-by-reference semantics, forcibly trying to pass objects by reference has not made good sense since PHP 4.
Just remove the & ...
Let's ignore that, and pretend there is still a problem, so that you can try to understand what is going on.
To break down the problem, first you need to understand the distinction between a variable and an expression:
mine(1 + 2);
The argument to mine has no name, it's represented by a temporary variable in the engine: it's an expression.
mine(1);
The argument to mine has no name, it's not an expression, but a literal constant, represented by a compiler variable in the engine. It's similar to a temporary variable, a kind of constant expression.
mine($a);
The argument to mine has a name, which you can use to refer to it's value. It's a normal variable.
Only variables can be passed by reference because you cannot refer to expressions or literal constants
Next you need to understand why we pass-by-reference:
function mine(int $thing) {
$thing++;
}
$a = 1;
mine($a);
var_dump($a); // int(1)
In this code, $a is passed to mine() by value, so that the changes that mine() make to $thing are only visible inside the scope of mine. $a is unchanged after the call to mine() returns because $a and $thing are distinct, having been passed-by-value, which means it's value was copied on to the call stack for the invocation of mine().
function mine(int &$thing) {
$thing++;
}
$a = 1;
mine($a);
var_dump($a); // int(2)
In the code above, $a is passed to mine() by reference, this means that $a and $thing are no longer distinct. The changes mine() make to $thing are now visible after the call to mine() returns.
The last piece in the puzzle is Reflection:
function mine(int &$thing) {
$thing++;
}
$a = 1;
$reflector = new ReflectionFunction("mine");
$reflector->invoke($a);
The code above will raise:
Warning: Parameter 1 to mine() expected to be a reference, value given in /usr/src/php-src/refs.php on line 9
This is because ReflectionFunction::invoke and similar reflection functions (ReflectionClass::newInstance) accept their parameters by value and pass them onto the invoked function by value.
But ...
There is still a difference between pass-by-reference semantics, and passing by reference, a dangerous one:
class Foo {
public function qux() {}
}
class Bar {}
function mine(Foo &$foo) {
$foo = new Bar();
}
$foo = new Foo;
mine($foo);
$foo->qux();
Will obviously yield:
PHP Fatal error: Uncaught Error: Call to undefined method Bar::qux() in /usr/src/php-src/refs.php:16
Stack trace:
#0 {main}
thrown in /usr/src/php-src/refs.php on line 16
The declaration of mine() tells lies about the type safety of it's parameter. Type safety is only guaranteed upon entry to the function, the function body is free to break type safety, but it doesn't usually affect the caller when relying on the engines pass by reference semantics for objects.
This is an extremely scary kind of API, that should be avoided.
Suppose I have a struct type Foo. I'm trying to create an std.container.Array of const pointers to Foo. I tried the obvious first:
import std.container;
alias FooArray = Array!(const(Foo*));
However, this causes a compiler error. Then I tried it with fewer parentheses:
alias FooArray = Array!(const Foo*);
But this gave the same error (error instantiating apparently). What am I doing wrong here?
Array probably needs to modify the reference (if not the object).
Try this:
alias FooArray = Array!(const(Foo)*);
I'd like to know how in C++/CLI it is possible to check whether an ArrayList is existent.
System::Collections::ArrayList %queue_tx
I tried if ( nullptr != queue_tx ) { queue_tx.Add(msg); } but that didn't work. I'm passing queue_tx as a parameter to a function and there's supposed to be the possibility of this parameter not being set (or being set to nullptr).
The compiler throws '!=' : no conversion from 'System::Collections::ArrayList' to 'nullptr'.
How do I do this?
% defines a reference variable this is why it cannot be null
if you would have declared the ArrayList like this:
System::Collections::ArrayList^ queue_tx
then your nullptr check would be possible and have a meaning
otherwise just use the queue_tx.Count() to check if the collection is empty
I would recommend going over:
the difference between reference and pointer variables
When to use a Reference VS Pointers
It is quite impossible for a T% to be null.
Here is the definition of my Package class:
type Package ([<ParamArray>] info : Object[]) =
do
info |> Array.iter (Console.WriteLine)
member this.Count = info.Length
and here is the IL, I'm trying:
let ilGen = methodbuild.GetILGenerator()
ilGen.Emit(OpCodes.Ldstr, "This is 1")
ilGen.Emit(OpCodes.Ldstr, "Two")
ilGen.Emit(OpCodes.Ldstr, "Three")
ilGen.Emit(OpCodes.Newobj, typeof<Package>.GetConstructor([|typeof<Object[]>|]))
ilGen.Emit(OpCodes.Ret)
but this doesn't seem to work. I tried:
ilGen.Emit(OpCodes.Newobj, typeof<Package>.GetConstructor([|typeof<String>; typeof<String>; typeof<String>|]))
a well as:
ilGen.Emit(OpCodes.Newobj, typeof<Package>.GetConstructor([|typeof<Object>; typeof<Object>; typeof<Object>|]))
but it just laughs at me. What am I doing wrong?
The [<ParamArray>] attribute indicates to a compiler that a method accepts a variable number of arguments. However, the CLR doesn't really support varargs methods -- it's just syntactic sugar provided by the C#/VB.NET/F# compilers.
Now, if you take away the [<ParamArray>], what are you left with?
(info : Object[])
That is the signature of the constructor you're trying to call.
So, you'll need to use the newarr and stelem opcodes to create an array, store the values into it, then call the constructor using the array as the argument. This should do what you want (though I haven't tested it):
let ilGen = methodbuild.GetILGenerator()
// Create the array
ilGen.Emit(OpCodes.Ldc_I4_3)
ilGen.Emit(OpCodes.Newarr, typeof<obj>)
// Store the first array element
ilGen.Emit(OpCodes.Dup)
ilGen.Emit(OpCodes.Ldc_I4_0)
ilGen.Emit(OpCodes.Ldstr, "This is 1")
ilGen.Emit(OpCodes.Stelem_Ref)
// Store the second array element
ilGen.Emit(OpCodes.Dup)
ilGen.Emit(OpCodes.Ldc_I4_1)
ilGen.Emit(OpCodes.Ldstr, "Two")
ilGen.Emit(OpCodes.Stelem_Ref)
// Store the third array element
ilGen.Emit(OpCodes.Dup)
ilGen.Emit(OpCodes.Ldc_I4_2)
ilGen.Emit(OpCodes.Ldstr, "Three")
ilGen.Emit(OpCodes.Stelem_Ref)
// Call the constructor
ilGen.Emit(OpCodes.Newobj, typeof<Package>.GetConstructor([|typeof<Object[]>|]))
ilGen.Emit(OpCodes.Ret)
NOTE: In this code, I used the dup OpCode to avoid creating a local variable to hold the array reference while storing the element values. This is only feasible because this code is fairly straightforward -- I strongly suggest you create a local variable to hold the array reference if you want to build something more complicated.
#include<QMetaType>
typedef QList<int> IntList;
qRegisterMetaType<IntList>("IntList");
error C2909: 'qRegisterMetaType': explicit instantiation of function template requires return type
C2909 says I need to define
template int qRegisterMetaType<IntList>("IntList");
If I define like I mentioned above then I get the below error
error C2059: syntax error : 'string'
warning C4667: 'int qRegisterMetaType(void)' : no function template defined that matches forced instantiation
why do I get this error ?
"qRegisterMetaType" is a function. It must appear in a code block.
int metatype_id = qRegisterMetaType<IntList>("IntList");
You need to add Q_DECLARE_METATYPE(IntList) before you can register it.