What is the difference between "= gcnew" and "+= gcnew"? - c++-cli

Please consider the following line of code:
port->DataReceived += gcnew SerialDataReceivedEventHandler(DataReceivedHandler);
What difference does the preceding + mean when used with the gcnew keyword?

The += operator does not apply to the gcnew operator but to the DataReceived event. You are instantiating a new SerialDataReceivedEventHandler delegate on the managed heap with the 'gcnew' operator, and you are adding it to the invocation list of the DataReceived event with of the += operator.

Related

kotlin Overload resolution ambiguity. All these functions match

kotlin/jvm jdk8 not support code
var buffer = StringBuffer();
var arr = arrayOf("1","2","3","4");
arr.forEach {buffer::append}
error info
java jdk8 supported code,
String[] b = new String[]{"c", "b"};
Arrays.stream(b).forEach(buffer::append);
In general, If you want to pass a method reference (buffer::append) to a method that takes a lambda, you need to enclose it in parentheses, not curly braces. In this specific case, you can't pass the append method as a method reference, because it returns StringBuilder, and forEach requires a method that returns Unit.
To make your code work, use a lambda:
arr.forEach { buffer.append(it) }
You can't copy-paste and use Stream code like that, because it ends up parsing it wrong. Since foreach blocks also contain the data, you can just do:
var buffer = StringBuffer();
var arr = arrayOf("1","2","3","4");
arr.forEach{buffer.append(it)}
The forEach block doesn't take a method as an argument, so doing buffer::append doesn't add any data, since you have to do that yourself

Hooking to empty C++ implementation with C++/CLI events

I am using an open source toolkit (VTK) that has an object with a method that is triggered by pressing any key. The idea is to overwrite the implementation in your own class but I can't figure out how to do it in C++/CLI.
This is what I have, but I can't figure out how to hook it to an object.
delegate void myEventHandler(vtkObject * sender, EventArgs ^ e);
event myEventHandler^ LeftButtonPressEvt;
LeftButtonPressEvt += gcnew myEventHandler(&MyClass::MyModifiedOnKeyPress);
void MyModifiedOnKeyPress(vtkObject * sender, EventArgs ^ e)
{
//this should be called whenever the button is pressed
}
Hooking it to the vtk object would look something like this:
vtkObject->OnKeyPress += gcnew myEventHandler(&MyClass::Pick);
This returns the error that a function is the left operand which makes sense, but I cant figure out how this would be hooked to the event.
For non-static methods, you need to specify which object the delegate should point to.
vtkObject->OnKeyPress += gcnew myEventHandler(this, &MyClass::Pick);
// ^^^^
(If that doesn't solve the problem, then I don't understand exactly what problem you're having. If you're getting an error message, don't describe the error, copy & paste exactly what the error message is.)

Modifying self in `iter_mut().map(..)`, aka mutable functional collection operations

How do I convert something like this:
let mut a = vec![1, 2, 3, 4i32];
for i in a.iter_mut() {
*i += 1;
}
to a one line operation using map and a closure?
I tried:
a.iter_mut().map(|i| *i + 1).collect::<Vec<i32>>();
The above only works if I reassign it to a. Why is this? Is map getting a copy of a instead of a mutable reference? If so, how can I get a mutable reference?
Your code dereferences the variable (*i) then adds one to it. Nowhere in there does the original value get changed.
The best way to do what you asked is to use Iterator::for_each:
a.iter_mut().for_each(|i| *i += 1);
This gets an iterator of mutable references to the numbers in your vector. For each item, it dereferences the reference and then increments it.
You could use map and collect, but doing so is non-idiomatic and potentially wasteful. This uses map for the side-effect of mutating the original value. The "return value" of assignment is the unit type () - an empty tuple. We use collect::<Vec<()>> to force the Iterator adapter to iterate. This last bit ::<...> is called the turbofish and allows us to provide a type parameter to the collect call, informing it what type to use, as nothing else would constrain the return type.:
let _ = a.iter_mut().map(|i| *i += 1).collect::<Vec<()>>();
You could also use something like Iterator::count, which is lighter than creating a Vec, but still ultimately unneeded:
a.iter_mut().map(|i| *i += 1).count();
As Ry- says, using a for loop is more idiomatic:
for i in &mut a {
*i += 1;
}

Complex check-methods with boost.test

I want to test different constructors of a string class. Therefore I wrote myself a test method that checks a couple standard things:
void checkStringStandards(String& s, size_t length, const char* text){
BOOST_CHECK_EQUAL(s.length(), length);
...
}
Then I added a test method
BOOST_AUTO_TEST_CASE(String_construct){
String s1;
checkStringStandards(s1, 0, "");
String s2("normal char");
checkStringStandards(s2, 11, "normal char");
}
The problem is, that when it fails, I only get the line- and file information from within checkStringStandards ! I can't know by the output whether the first or the second call caused this.
What's the common fix for that?
Cheers!
The solution to this problem is to write a custom predicate that performs the checks and use BOOST_REQUIRE(custom_predicate(args)) in the different test cases. A custom predicate can take any arguments you want and returns boost::test_tools::predicate_result, a type that is compatible with the assertion macros in Boost.Test into which you can build up a detailed diagnostic message during failure.
To use your example:
using namespace boost::test_tools;
predicate_result checkStringStandards(String& s, size_t length, const char* text) {
predicate_result result{true};
if (s.length() != length) {
result = false;
result.message() << "\nString " << s
<< " differs in length; expected: "
<< length << ", actual: " << s.length();
}
...
return result;
}
BOOST_AUTO_TEST_CASE(String_construct){
String s1;
BOOST_REQUIRE(checkStringStandards(s1, 0, ""));
String s2("normal char");
BOOST_REQUIRE(checkStringStandards(s2, 11, "normal char"));
}
The curious \n at the beginning of the message is so that when the diagnostic is printed, the text with "String ... differs in length" will be emitted on it's own line. If the predicate fails, it bubbles its failure up to BOOST_REQUIRE which will trigger the test failure and report the failure at the line invoking BOOST_REQUIRE instead of inside your custom predicate.
There is another yuckier alternative that also achieves the same result by making your custom assertions as gigantic megamacros, but I find that so horrid I'm not even going to show an example of how to do it :).
there is no common fix for that. these BOOST_CHECK_... macros exist by intention to avoid function calls where the line number gets lost (unless explicitely passed as param).
you can get round this problem by looping through the parameter set inside your test case.

AIR Sqlite: SQLEvent.RESULT not firing, but statement IS executing properly

Ok it looks likes like I have stumbled upon a strange timing issue... I made a quick SQL wrapper class for executing sql statements. However after .execute() is called, the SQLEvent.RESULT event is never fired, but the new entry in the DB is created as it should be. The really really odd part is if I put a setTimeout() just after calling execute() the event fires as expected.. I hope I'm missing something really obvious here... Here is a link to an example air app:
http://www.massivepoint.com/airsqltest/AIRSQL.zip
And here is the code to the wrapper class:
if you look down at line 51 in the SQLRequest class, you will see the commented out setTimeout() method. To make everything work, just uncomment that line.. but to me this doesn't make any sense...
anyone have any thoughts? I'm totally stumped here...
package com.jac.sqlite
{//Package
import flash.data.SQLConnection;
import flash.data.SQLStatement;
import flash.events.EventDispatcher;
import flash.events.SQLErrorEvent;
import flash.events.SQLEvent;
import flash.utils.setTimeout;
public class SQLRequest extends EventDispatcher
{//SQLRequest Class
private var _callback:Function;
private var _dbConn:SQLConnection;
private var _query:String;
private var _params:Object;
private var _statement:SQLStatement;
public function SQLRequest(callback:Function, connection:SQLConnection, query:String, parameters:Object=null):void
{//SQLRequest
trace("Creating new SQL Request");
_callback = callback;
_dbConn = connection;
_query = query;
_params = parameters;
_statement = new SQLStatement();
_statement.sqlConnection = _dbConn;
_statement.text = _query;
if (_params != null)
{//assign
for (var param:String in _params)
{//params
trace("Setting Param: " + param + " to: " + _params[param]);
_statement.parameters[param] = _params[param];
}//params
}//assign
//setup events
_statement.addEventListener(SQLEvent.RESULT, handleResult, false, 0, true);
_statement.addEventListener(SQLErrorEvent.ERROR, handleError, false, 0, true);
}//SQLRequest
public function startLoad():void
{//execute
_statement.execute();
//setTimeout(handleTimeOut, 10000);
}//execute
//TEMP
private function handleTimeOut():void
{//handleTimeOut
trace("Executing: " + _statement.executing + " / " + executing);
}//handleTimeOut
private function handleResult(e:SQLEvent):void
{//handleResult
trace("Good SQL Request");
_callback(e);
dispatchEvent(e);
}//handleResult
private function handleError(e:SQLErrorEvent):void
{//handleError
trace("SQL Error: " + e.errorID + ": " + e.error);
//dispatchEvent(e);
}//handleError
public function get executing():Boolean
{//get executing
return _statement.executing;
}//get executing
public function get query():String { return _query; }
public function get statement():SQLStatement { return _statement; }
}//SQLRequest Class
}//Package
I think what you're missing here is garbage collection.
Haven't tested your code, but this could certainly be the source of the problem.
var sqlReq:SQLRequest = new SQLRequest(handleResult, _dbConn, sql);
sqlReq.startLoad();
The reference sqlReq is local to the function and becomes unreacheable when the function returns. That makes it collectable. I guess there must be some code in the AIR runtime that collects garbage more agressively when there are sql connections involved. Because generally, you'll get away with not storing a ref to your object (at least in a web based environment, in my experience; this is a bug in such code, nevertheless; you just have to be in a bad day to experience it).
The setTimeout masks this problem (or almost solves it, although in an unintended way), because the setTimeout function uses a Timer internally. Running timers are not collected. So, the timer is alive and kicking and has a reference to your SQLRequest instance, which makes it reacheable, and so, not elligible for collection. If your DB call takes longer than the timeout though, you're back in the same situation.
To solve this, store a ref to the object and dispose it properly when you're done.
Edit
Another option, if you don't want to change the way you calling code works, is storing a ref to the instance in a class-scoped (i.e. static) dictionary for the duration of the call (this dictionary shoul not use weak referenced keys for obvious reasons).
You are adding a hidden side effect to your method, which is not a sign of good design in general, but as long as you remove it when the call to the DB is finished (whether it succeded or not), you're safe, so I think the problem is more of style than anything else.
What I mean is something like this:
private static var _dict:Dictionary = new Dictionary();
public function startLoad():void
{//execute
_statement.execute();
// add a self reference to dict so the instance won't be collected
// do this in the last line, so if we have an exception in execute, this
// code will not run (or add a try/catch if you want, but this is simpler
// and cleaner, IMO
addToDict();
}//execute
private function handleResult(e:SQLEvent):void
{//handleResult
// remove the self reference before running any other code
// (again, this is in case the code that follows throws)
removeFromDict();
trace("Good SQL Request");
_callback(e);
dispatchEvent(e);
}//handleResult
private function handleError(e:SQLErrorEvent):void
{//handleError
// same comment as handleResult
removeFromDict();
trace("SQL Error: " + e.errorID + ": " + e.error);
//dispatchEvent(e);
}//handleError
private function addToDict():void {
_dict[this] = true;
}
private function removeFromDict():void {
if(_dict[this]) {
delete _dict[this];
}
}