I'm trying to store QScopedPointers in a QList.
I found this comment
One can also use QList >. – Kuba Ober Jan 14 '14 at 18:17
(first comment on this answer: https://stackoverflow.com/a/21120575/3095014)
and this post https://forum.qt.io/topic/59338/solved-qlist-of-qscopedpointers which implies that this should work. But if I try to compile the code of the second link, I'm getting this errors:
E:\Qt\Qt5Enterprise\5.5\msvc2013\include\QtCore/qlist.h(404) : error C2248: 'QScopedPointer<Label,QScopedPointerDeleter<T>>::QScopedPointer' : cannot access private member declared in class 'QScopedPointer<Label,QScopedPointerDeleter<T>>'
with
[
T=Label
]
E:\Qt\Qt5Enterprise\5.5\msvc2013\include\QtCore/qscopedpointer.h(170) : see declaration of 'QScopedPointer<Label,QScopedPointerDeleter<T>>::QScopedPointer'
with
[
T=Label
]
E:\Qt\Qt5Enterprise\5.5\msvc2013\include\QtCore/qlist.h(403) : while compiling class template member function 'void QList<QScopedPointer<Label,QScopedPointerDeleter<T>>>::node_construct(QList<QScopedPointer<T,QScopedPointerDeleter<T>>>::Node *,const QScopedPointer<T,QScopedPointerDeleter<T>> &)'
with
[
T=Label
]
E:\Qt\Qt5Enterprise\5.5\msvc2013\include\QtCore/qlist.h(553) : see reference to function template instantiation 'void QList<QScopedPointer<Label,QScopedPointerDeleter<T>>>::node_construct(QList<QScopedPointer<T,QScopedPointerDeleter<T>>>::Node *,const QScopedPointer<T,QScopedPointerDeleter<T>> &)' being compiled
with
[
T=Label
]
E:\Qt\Qt5Enterprise\5.5\msvc2013\include\QtCore/qlist.h(794) : while compiling class template member function 'QList<QScopedPointer<Label,QScopedPointerDeleter<T>>>::~QList(void)'
with
[
T=Label
]
..\tableview_row_dnd\main.cpp(13) : see reference to function template instantiation 'QList<QScopedPointer<Label,QScopedPointerDeleter<T>>>::~QList(void)' being compiled
with
[
T=Label
]
..\tableview_row_dnd\main.cpp(20) : see reference to class template instantiation 'QList<QScopedPointer<Label,QScopedPointerDeleter<T>>>' being compiled
with
[
T=Label
]
E:\Qt\Qt5Enterprise\5.5\msvc2013\include\QtCore/qlist.h(405) : error C2248: 'QScopedPointer<Label,QScopedPointerDeleter<T>>::QScopedPointer' : cannot access private member declared in class 'QScopedPointer<Label,QScopedPointerDeleter<T>>'
with
[
T=Label
]
E:\Qt\Qt5Enterprise\5.5\msvc2013\include\QtCore/qscopedpointer.h(170) : see declaration of 'QScopedPointer<Label,QScopedPointerDeleter<T>>::QScopedPointer'
with
[
T=Label
]
Why isn't this working for me?
Values stored in Qt containers should be of assignable data types. That means they should have a default constructor, a copy constructor, and an assignment operator.
QScopedPointer has its copy constructor and assignment operator disabled. You can't assign two pointers to each other, but you can explicitly transfer the ownership of the underlying raw pointer using QScopedPointer::reset, QScopedPointer::swap or QScopedPointer::take.
At some point a move constructor and a move assignment operator were added to QScopedPointer. New move semantics made this possible:
QList<QScopedPointer<Label>> mLabels;
mLabels.append(QScopedPointer<Label>(new Label));
Here a temporary value is added to a list and the new list item is created using the move constructor.
Later they reverted that change:
Adding a move contructor to QScopedPointer makes no sense, because
moving means 'escaping the scope', which breaks the fundamental point
of QScopedPointer.
If you really want to have a list of smart pointers, you can use QSharedPointer which is assignable or std::unique_ptr which supports move semantics.
And if you talk about tracking lifetime of QObjects subclasses and especially widgets, I would suggest to use Qt child-parent mechanism rather than smart pointers.
Related
I tried to create an interface to create tagged services that can be injected into another service based on the documentation here https://symfony.com/doc/3.4/service_container/tags.html
I created an interface like
namespace AppBundle\Model;
interface PurgeInterface {
//put your code here
public function purge ();
}
put the definition into the service.yml:
_instanceof:
AppBundle\Model\PurgeInterface:
tags: ['app.purge']
and create services on this interface.
console debug:container shows my services as properly tagged.
I created another service which should work with the tagged services but this do not work.
services.yml:
purge_manager:
class: AppBundle\Service\PurgeManager
arguments: [!tagged app.purge]
The service looks like:
namespace AppBundle\Service;
use AppBundle\Model\PurgeInterface;
class PurgeManager {
public function __construct(iterable $purgers) {
dump($purgers);
}
}
If I test this I get:
Type error: Too few arguments to function AppBundle\Service\PurgeManager::__construct(), 0 passed in /.....Controller.php on line 21 and exactly 1 expected
I haven´t tried to create a compiler pass because I just want to understand why this is not working as it should based on the documentation
Thanks in advance
Sebastian
You can use tags, manual service definition and _instanceof in config. It's one of Symfony ways, but it requires a lot of YAML coding. What are other options?
Use Autowired Array
I've answered it here, but you use case much shorter and I'd like to answer with your specific code.
The simplest approach is to autowire arguments by autowired array.
no tag
support PSR-4 autodiscovery
no coding outside the service
1 compiler pass
Example
namespace AppBundle\Service;
use AppBundle\Model\PurgeInterface;
class PurgeManager
{
/**
* #param PurgeInterface[] $purgers
*/
public function __construct(iterable $purgers) {
dump($purgers);
}
}
This is also called collector pattern.
How to Integrate
Read a post with an example about this here
Or use the Compiler pass
If there are some incompatible classes, exclude them in the constructor of compiler pass:
$this->addCompilerPass(new AutowireArrayParameterCompilerPass([
'Sonata\CoreBundle\Model\Adapter\AdapterInterface'
]);
I have this class
class ScanRequest4Command implements Validateable {
String _ScanType
static constraints = {
pScanType inList:["a", "b"]
}
}
this code worked fine in grails 2.4.4
lately, we started upgrading to grails 3.1.16
now when I try to run the code if fails and throw the following exception:
java.lang.IllegalArgumentException: object is not an instance of declaring class
at com.evercompliant.commands.v4.ScanRequest4Command$__clinit__closure9.doCall(ScanRequest4Command.groovy:151)
at com.evercompliant.commands.v4.ScanRequest4Command$__clinit__closure9.doCall(ScanRequest4Command.groovy)
at com.evercompliant.commands.v4.ScanRequest4Command$__clinit__closure9.call(ScanRequest4Command.groovy)
at com.evercompliant.commands.v4.ScanRequest4Command$__clinit__closure9.call(ScanRequest4Command.groovy)
at com.evercompliant.commands.v4.ScanRequest4Command.validate(ScanRequest4Command.groovy)
at com.evercompliant.commands.v4.ScanRequest4Command.validate(ScanRequest4Command.groovy)
at com.evercompliant.commands.v4.Base4Command.validateWithErrors(Base4Command.groovy:98)
at com.evercompliant.commands.v4.PortfolioManagementBase4Command.validateWithErrors(PortfolioManagementBase4Command.groovy)
at com.evercompliant.commands.v4.ScanRequest4Command.super$2$validateWithErrors(ScanRequest4Command.groovy)
at com.evercompliant.commands.v4.ScanRequest4Command.validateWithErrors(ScanRequest4Command.groovy:164)
at com.evercompliant.commands.v4.ScanRequest4Command$validateWithErrors.call(Unknown Source)
at com.evercompliant.data.Merchant.withTransaction(Merchant.groovy)
at com.evercompliant.data.Merchant$withTransaction.call(Unknown Source)
at com.evercompliant.utils.CorsFilter.doFilterInternal(CorsFilter.java:35)
which did not help much.
if I remove the inList constraint the code passes, meaning the problem is in the inList constraint.
so after test-and-failed, I found out the if I change the member's name to pScanType the code passes.
so my question is this:
is the underscore not allowed in member name prefix? if so is it
documented anywhere? if not then what is the problem with the code?
Here is the issue. Let assume I have two mutable modules:
class DbModule extends Module { bind[JdbcBackend#Database] toProvider
inject[JdbcDriver].backend.Database.forURL(
inject[String]("db.url"),
inject[String]("db.username"),
inject[String]("db.password"), null,
inject[String]("db.driver")
) }
and here is the corresponding config:
resources/application.conf:
db { url="postgres url" username="db_user" password="db_password" driver="cc" }
Somewhere in the code I do:
implicit val inj = TypesafeConfigInjector() :: new AppModule
However this injector gives the following exception:
caldi.InjectException: No binding found with following identifiers:
* TypeTagIdentifier(String) * StringIdentifier(db.url)
The order in Scaldi is important: the binding is resolved from left to right.
The :: operator, as stated in the docs, composes two injectors by inverting the operands. Thus, in your case, AppModule is resolved first, hence it cannot find the config params injected.
To solve your problem, use the ++ operator to keep your injectors in order.
I hope this is helpful.
I don't understand why this does not work?
import CoreImage
class RectDetector: CIDetector {
convenience init?(aspectRatio: Float) {
let options: [String : Any] = [CIDetectorAccuracy : CIDetectorAccuracyHigh,
CIDetectorAspectRatio : NSNumber(value: aspectRatio)]
self.init(ofType: CIDetectorTypeRectangle, context: nil, options: options)
}
}
I'm getting error "Ambiguous reference to member init(aspectRatio:)".
If I try to add default value for aspect ratio like this:
import CoreImage
class RectDetector: CIDetector {
convenience init?(aspectRatio: Float = 1.0) {
let options: [String : Any] = [CIDetectorAccuracy : CIDetectorAccuracyHigh,
CIDetectorAspectRatio : NSNumber(value: aspectRatio)]
self.init(ofType: CIDetectorTypeRectangle, context: nil, options: options)
}
}
then I get error "Argument passed to call that takes no arguments".
Is this a bug? Why I can't subclass CIDetector with custom convenience initializer which is chaining to existing initializer?
P.S. I'm using Xcode 8.2 (8C38)
Swift imports some class methods as convenience initializers (Class Factory Methods and Convenience Initializers).
In your case, init(ofType:context:options:) is a class method of CIDetector in Objective-C + detectorOfType:context:options:.
Such convenience initializers are not available in subclasses. It's a natural conclusion based on the fact that such factory method of a class always creates an instance of the class, it cannot create an instance of the subclass you defined.
So, if you want to provide another convenience initializer utilizing a convenience initializer based on Class Factory Method, you may need an extension.
extension CIDetector {
convenience init?(rectDetectorWithAspectRatio aspectRatio: Float) {
let options: [String : Any] = [CIDetectorAccuracy : CIDetectorAccuracyHigh,
CIDetectorAspectRatio : NSNumber(value: aspectRatio)]
self.init(ofType: CIDetectorTypeRectangle, context: nil, options: options)
}
}
By the way, the diagnostics messages are seemingly completely broken from the programmers' side using Swift. You can send a Bug Report about it.
I'm looking for way of exposing config settings across application, where I can in any bundle add what I want. Purpose of this is to expose several things to HTML, parse it and use in JS.
Base part is ConfigService to which can be added ConfigUnit with own logic.
ConfigServiceInterface:
public function getConfig();
public function addUnit(ConfigUnitInterface $unit);
ConfigUnitInterface:
public function getName();
public function getConfig();
best would be to add units in service.yml like this:
services:
service.config:
class: ConfigService
calls:
- [ addUnit, [ "#unit" ] ]
- [ addUnit, [ "#unit2" ] ]
but config service should be declared in some bundle and developer can't change it's declaration.
second thing which comes to my mind was declare units with calling register method which would get ConfigService as parameter.
config_unit:
class: ConfigUnit
arguments: [...]
calls:
- [ register, [ "#service.config" ] ]
but this isn't nice and I must get this service to init calls, so I must get it from container each time.
Is there way to do this automatically? And separate as possible?
Maybe event would be nice for this, but I don't want to allow developer to modify config array directly.
Well I found out how to do it.
documentation helps:
tags, compiler pass
Each my unit has now tag: 'config.unit'
config_unit:
class: ConfigUnit
arguments: [...]
tags:
- { name: config.unit }
these are processed by CompilerPass and injected to ConfigService