Returning NULL Structure - opencv

I am calling a function which returns a structure of the type CvBox2D, however I want to check for an error in the function and return NULL if there is an error.
CvBox2D function()
{
...
if(ERROR)
return NULL;
...
}
I am getting an error : cannot convert from 'int' to 'CvBox2D'

Your function return type is CvBox2D, so you can't convert a (NULL) pointer to it.
If you really need to return "nothing" if the check inside the function fails, you can change the return type to a pointer to CvBox2D:
CvBox2D* function()
{
...
}
You will also have to change the way the returned object is created inside your function.
Note that using raw pointers in C++ usually isn't a good idea.
Take a look at std::shared_ptr (available in C++11) if you think you really have to use pointers.

If you want to return some error code, you can do the following:
int function(CvBox2D* output) {
// code...
// Assign to struct.
output->center = ...;
if (error) {
return RC_ERROR_FOO;
}
return RC_OK;
}
Then you call this function using a struct you've already allocated (for example, on the stack):
{
CvBox2D myBox;
int retval = function(&myBox);
if (RC_OK == retval) {
printf("Good! Angle of box: %g", myBox.angle);
} else {
printf("Error: %d", retval);
}
}
Where RC_OK, RC_ERROR_FOO are defined as constant integers, or better, as an enum (if you're using C++).

The other answers solve your problem, but if you want to keep the signature of your function, instead of returning an error code, you should throw an exception.

Related

Bang operator vs assert statements

In the code below, I'm casting away the nullability by using the bang operator.
void main() {
String? foo;
foo!.toLowerCase();
}
But when I use assert just before calling the function, I get an error.
void main() {
String? foo;
assert(foo != null);
foo.toLowerCase(); // Error
}
Is bang operator not doing the same thing behind the scene?
Note: I'm not looking for a solution to how to make it work, there are many ways, even the flow statement ones, if (foo == null) return;
(Adding this an answer instead of a comment.)
The point of asserts is that they can be disabled and that they will not incur any runtime penalty. It's been some matter of debate, but the current philosophy is that this means that asserts will not perform type promotion, so even if you do:
bool foo(Object object) {
assert(object is String);
// error: The getter 'isEmpty' isn't defined for the type 'Object'
return object.isEmpty;
}
For the same reason, assert(someLocalVariable != null) will not promote someLocalVariable to a non-nullable type:
bool bar(String? string) {
assert(string != null);
// error: The property 'isEmpty' can't be unconditionally accessed
// because the receiver can be null.
return string.isEmpty;
}
As of Dart 2.12 with null-safety enabled, however, you can get the desired effect by just performing the cast directly. That will promote the type and throw a runtime exception if the cast fails:
bool foo(Object object) {
object as String;
return object.isEmpty;
}
bool bar(String? string) {
string!;
return string.isEmpty;
}

Dart: lists of supertype takes subtype only at runtime

I ran into an issue similar to this:
void main() {
_buildMixedList([1,2.3,4,5.6,7.6,8]);
_buildHomogeneousList([1,2,4,5,7,8]);
}
abstract class NumberWrapper {}
class DoubleWrapper extends NumberWrapper{
final double myDouble;
DoubleWrapper(this.myDouble);
}
class IntWrapper extends NumberWrapper{
final int myInt;
IntWrapper(this.myInt);
}
List<NumberWrapper?> _buildMixedList(List<dynamic> numbers) {
List<NumberWrapper?> wrappers = numbers.map((number) {
if(number is int){
return IntWrapper(number);
}
if(number is double){
return DoubleWrapper(number);
}
return null;
}).toList();
wrappers.add(DoubleWrapper(0.2));
return wrappers;
}
List<NumberWrapper?> _buildHomogeneousList(List<dynamic> numbers) {
List<NumberWrapper?> wrappers = numbers.map((number) {
if(number is int){
return IntWrapper(number);
}
return null;
}).toList();
wrappers.add(DoubleWrapper(0.2));
return wrappers;
}
As you can see, the two methods are doing something similar (adding object of different types to a list). The first one adds different objects inside a map() function and the other adds only one type in map() and then adds another after.
The second one throws this error:
: TypeError: Instance of 'DoubleWrapper': type 'DoubleWrapper' is not a subtype of type 'IntWrapper?'Error: TypeError: Instance of 'DoubleWrapper': type 'DoubleWrapper' is not a subtype of type 'IntWrapper?'
As if the list is being changed to List<IntWrapper?> just because we only added IntWrappers in the map().
I wrote this test code after encountering this in one of my projects, so it's not representative of a real case. I tried it on dartPad.
Coming from a java background I was expecting the second method to work. Is it a bug or is it intended? If intended, why is that so?
Your problem is that there are a difference between the type of the variable and the type of the object which you are pointing to.
So in this case:
List<NumberWrapper?> wrappers = numbers.map((number) {
if(number is int){
return IntWrapper(number);
}
return null;
}).toList();
What you are actually are doing is creating a List<IntWrapper?> which you are using a variable of the type List<NumberWrapper?> to point at. Why? Because the type of the variable in this case does not change the type of the returned List from toList() (which type is determined by what type map() returns).
The reason the type is List<IntWrapper?> is because Dart are trying to be smart about automatically assigning the type. In this case, the analyzer can see you List will only contain IntWrapper or null.
I think the best solution here is to rewrite this part to something like this:
List<NumberWrapper?> _buildHomogeneousList(List<num> numbers) {
final wrappers = <NumberWrapper?>[
for (final number in numbers)
if (number is int) IntWrapper(number) else null
];
wrappers.add(DoubleWrapper(0.2));
return wrappers;
}
By using the [] syntax to create the List, it is easier to specify the type you want the List to be.
Alternative, you can do this where we add the expected type to the map method:
List<NumberWrapper?> _buildHomogeneousList(List<num> numbers) {
List<NumberWrapper?> wrappers = numbers.map<NumberWrapper?>((number) {
if (number is int) {
return IntWrapper(number);
}
return null;
}).toList();
wrappers.add(DoubleWrapper(0.2));
return wrappers;
}

What does the exclamation mark mean before a function call?

I was following a PR for Flutter and came across this code:
if (chunkCallback != null) {
chunkCallback!(0, 100);
}
What does the exclamation mark mean after chunkCallback? Nothing I search on Google works.
"!" is a new dart operator for conversion from a nullable to a non-nullable type.
Read here and here about sound null safety.
Use it only if you are absolutely sure that the value will never be null and do not confuse it with the conditional property access operator.
chunkCallback is a nullable reference to a function.
If you are sure that chunkCallback can't be null at runtime you can "Cast away nullability" by adding ! to it to make compiler happy
typedef WebOnlyImageCodecChunkCallback = void Function(
int cumulativeBytesLoaded, int expectedTotalBytes);
...
class Class1 {
final WebOnlyImageCodecChunkCallback? chunkCallback;
Class1(this.chunkCallback);
void test() {
if (chunkCallback == null) {
throw Exception("chunkCallback is null");
}
chunkCallback!.call(0, 100);
}
}
Esentially, ! in this case is a syntactic sugar for
(chunkCallback as WebOnlyImageCodecChunkCallback).call(0, 100);
I think it is a shorthand syntax for “Casting away nullability”, as per the docs: https://dart.dev/null-safety/understanding-null-safety#null-assertion-operator
The variable chunkCallback must be able to accept null and you cannot call a function on a nullable type without either using ! or ?. This is part of Darts sound null safety
Some great videos on this:
Flutter vid
YouTube vid
Even though the conditional statement checks for null, Dart still requires the exclamation mark before the function call. The difference between using ! over ? is that it will throw an exception instead of using the variable if the value is null.
Some examples:
class Car {
String? make; // String or null type
Car([this.make]); // parameter is optional
}
main() {
Car test = Car('Ford'); // initialised with a value
Car test2 = Car(); // no value given so null is default
// returns 4
if (test.make != null) {
print(test.make!.length); // ! still needed even though !=null condition stated
} else {
print('The value is null');
}
// returns The value is null
if (test2.make != null) {
print(test2.make!.length);
} else {
print('The value is null');
}
}
Above example shows that conditional check for null is not enough.
And choosing between ? and !
class Customer {
String? name;
String? surname;
Customer(this.name, [this.surname]); // constructor with optional parameter []
}
main() {
Customer ford = Customer('John'); //only name is given a value
// calling a method on a nullable type doesn't work
// so ? and ! used here after variable name and before method
print(ford.name!.length); // operation executed as usual => 4
print(ford.surname?.length); // ? on null value returns null => null
print(ford.surname!.length); // Exception is thrown => TypeError
}

Multiple types for a single variable (parameter/return type)

I am very new to Dart so excuse me if I didnt see this part.
I want to make a union type e.g. for a function input. In TS this would be:
let variableInput: string | number
typedef doesnt really define types but functions and enums dont really help too.
On the other side how should it look like when a function return either one or the other of two types? There must be something I dont see here.
There are no union types in Dart.
The way to do this in Dart is returning/accepting dynamic as a type:
dynamic stringOrNumber() { ... }
void main() {
final value = stringOrNumber();
if (value is String) {
// Handle a string value.
} else if (value is num) {
// Handle a number.
} else {
throw ArgumentError.value(value);
}
}
See also: https://dart.dev/guides/language/sound-dart

How to prevent function return result declaratively?

Assume such conditions:
Some operation does not provide possibility of returning the result.
This operation declared as callback
Using typedef not recommended
Some operation provide of returning the result.
This operation declared as callback
Using typedef not recommended
Assume such scenario:
void main() {
executeVoidOperation(methodNonVoid); // Must throw if method void?
executeNonVoidOperation(methodVoid); // Must throw if method non-void?
}
int methodNonVoid() {
return 0;
}
void methodVoid() {
}
void executeVoidOperation(void operation()) {
operation(); // Must throw if method non-void?
}
void executeNonVoidOperation(dynamic operation()) {
var result = operation(); // Must throw if method void?
print(result); // Result of void operation? (if such passed as argument)
}
Displayed results:
null
Questions (where I wrong?):
Null is object. From where this null appeared (as result) if void function cannot return result (even null)?
Functions with different return types in Dart assumed as the same (not conflicting) types?
How in Dart called this function transformations?
executeNonVoidOperation(methodVoid); works because the callback is defined as dynamic operation(). dynamic can be anything, including void. It's the same as if you just don't specify a type.
The null value stems from a simple rule in Dart. Quoted from the Dart Language Tour:
All functions return a value. If no return value is specified, the statement return null; is implicitly appended to the function body.
That means that every void method always returns null. If you try to return something else, you'll get a runtime error (in checked mode).
executeVoidOperation(methodNonVoid); is a bit more tricky - I'd expect it to throw a runtime error, but it seems the callback is treated as dynamic operation() instead of void operation(). Dart Editor's analyzer seems to think that, too. This may be either a bug or a design choice by the Dart team.

Resources