I'm rather new at this, but I need to create a TStringList in one function, pass it to another function to modify it, then use the results back in the first function. However, everything I try reports an error:
No matching function call.
Calling function:
std::unique_ptr<TStringList>metaData(new TStringList());
...
_retVal = ParseOMT(inpBuf, &metaData, _reportIt);
...
ParseOMT.h:
bool ParseOMT(const String ABuffer, TStringList* _currMetadata, String &_reportIt);
ParseOMT.cpp
bool ParseOMT(const String ABuffer, TStringList* _metadata, String &_reportIt) {
I have tried various combinations of the * and & in the ParseOMT() declaration and calling function, to no avail.
Can anybody help?
Your ParseOMT() function as shown is fine. The code that is calling it is wrong.
std::unique_ptr has a get() method which returns the object pointer being held.
So, simply change this:
_retVal = ParseOMT(inpBuf, &metaData, _reportIt);
To this instead:
_retVal = ParseOMT(inpBuf, metaData.get(), _reportIt);
Related
I'm very new to programming and Dart. I was wondering why you put Response in front of the variable response. Also why do we use Datetime object in front of the variable 'now?' I believe when you want to instantiate, you write Datetime now = Datetime(); But it was written something else for the variable. What does it mean? Thank you very much in advance!
void getTime() async{
Response response = await get(Uri.parse('https://worldtimeapi.org/api/timezone/Europe/London'));
Map data = jsonDecode(response.body);
// get properties from data
String datetime = data['datetime'];
String offset = data['utc_offset'].substring(1,3);
//create DateTime object
DateTime now = DateTime.parse(datetime);
now = now.add(Duration(hours: int.parse(offset)));
print(now);
}
Ok, let's break this down:
Response response = await
get(Uri.parse('https://worldtimeapi.org/api/timezone/Europe/London'));
A variable declaration in Dart looks like this:
<Type> <name> [= <value>];
So in your case Response is the type of the variable, response is the name of the variable and get(Uri.parse('https://worldtimeapi.org/api/timezone/Europe/London')) is the value of the variable (actually get(...) is a future, and the future's response is the value, that's why the await keyword is there, but that's not important.)
Sidenote, you can actually use the var keyword to skip the <Type> part of the declaration:
int myFunction(a, b) => a+b;
int x = myFunction(1,2);
Above, we know myFunction returns an int, and the variable x is equal to the result of myFunction, so it must also be an int, we can use the var keyword to skip writing int then:
int myFunction(a, b) => a+b;
var x = myFunction(1,2);
Of course, here there isn't that big a difference between writing int and var, but when your type is something like List<Map<String, List<int>>> it is quite nice to be able to skip writing that over and over
Now for this line:
DateTime now = DateTime.parse(datetime);
We already know that the first DateTime tells us what type the variable is, and we know that now is the name of the variable, we also know that the variable's value is DateTime.parse(datetime) because it is what goes after the = sign, but we still don't know what DateTime.parse(datetime) means.
Classes can have static and non-static methods, a static method is a method that gets called on a class, while a non-static method gets called on an object. Most method calls ever are non-static, look at this example:
class Car {
void accelerate() {
// some method to increase the speed of the car
}
void decelerate() {
// some method to decrease the speed of the car
}
Car buyCar(int maxCost) {
// some method to buy a new car
}
}
void main() {
Car car = Car();
car.accelerate();
car.decelerate();
Car otherCar = car.buyCar(100000000);
}
Above, the method accelerate and decelerate are instance methods and that makes sense because they probably affect some statistics of the car (like current speed), buyCar is also an instance method, but if you think about it, it shouldn't be, it doesn't affect your current car if you buy a new one and also you shouldn't need to have a car object to buy another one in the first place. So let's make that last method static:
class Car {
void accelerate() {
// some method to increase the speed of the car
}
void decelerate() {
// some method to decrease the speed of the car
}
static Car buyCar(int maxCost) {
// some method to buy a new car
}
}
It is as simple as adding the static keyword, now instead of having to do this:
Car myOldCar = Car();
Car myNewCar = myOldCar.buyCar(100000000);
we can just do this:
Car myNewCar = Car.buyCar(100000000);
looks familiar?
That's right parse is a static method on DateTime class, it takes a string that looks like this: 2012-02-27 13:27:00.123456789z and returns a DateTime object.
So to recap:
Response response = await
get(Uri.parse('https://worldtimeapi.org/api/timezone/Europe/London'));
Response is the type of the variable, response is its name and get(Uri.parse('https://worldtimeapi.org/api/timezone/Europe/London')) is a method that returns a Response object.
DateTime now = DateTime.parse(datetime);
Similarly DateTime is the type, now is the name and DateTime.parse is a static method that parses a string and makes a DateTime object, in this case the string is datetime, which was declared as being equal to data['datetime'].
If you want to understand better how the parse method works, here is the DateTime parse documentation
I was trying out the new ref returns of C#7.
I am able to compile and build this:
public ref string MisUseRefReturn(int index)
{
string[] array = { "a", "b", "c", "d" };
return ref array[index]; //array[2] gets out of scope when this method returns!
}
According to MSDN: The return value cannot be a local variable in the method that returns it; it must have a scope that is outside the method that returns it. It can be an instance or static field of a class, or it can be an argument passed to the method. Attempting to return a local variable generates compiler error CS8168, "Cannot return local 'obj' by reference because it is not a ref local."
So why does this compile? When I execute this method, the returned reference shows the correct string.
Think of the array element as if it were an instance field of the array. Imagine your array were:
public class FourElementStringArray
{
public string element0;
public string element1;
public string element2;
public string element3;
}
Then your code is equivalent to:
public ref string MisUseRefReturn(int index)
{
var array = new FourElementStringArray
{
element0 = "a",
element1 = "b",
element2 = "c",
element3 = "d"
};
// TODO: do this dynamically based on index
return ref array.element2;
}
That abides by the piece of documentation you quoted:
It can be an instance or static field of a class, or it can be an argument passed to the method.
Is this useful? Not particularly. Is it dangerous? No.
The latter part is the important point. Using the regular array, if the caller assigns a new value, that's fine - it's replacing an element of an array, on the heap. The array can't be garbage collected while the array element reference exists; all is basically okay.
What the compiler rule is trying to prevent is the use of a returned reference to somewhere on the stack which has then been popped by the method returning. The array itself isn't on the stack, so there's no problem here.
See the description here:
Returning a local int variable instead of an array is not possible.
int is a value type, and thus the variable gets out of scope at the
end of the method, and thus a reference to it cannot be returned.
That’s different with an array. An array is a reference type, and the
array is allocated on the heap. An int within the array can be
returned with the ref keyword.
You could not return an integer value directly as it is a value type. An array element can be returned because it is a reference type. The MSDN statement is correct.
... of an array that only exists inside the method
The returned reference persists the array beyond the method call.
I'm trying to display a dynamically updated array in a label using:
for i in result {
outputLbl.text = result[i].joinWithSeparator("\n")
}
However I get the error
Cannot subscript a value of type '[String]' with an index of type 'String'.
Any idea how I can fix this?
Note that when using the loop "header" for X in Y, you don't get the indices of Y, but the actual elements of Y. Judging from your error, results is an array of strings ([String]). Hence, i in you for loop represents---one by one---the elements in the String array results.
So, if you wanted to access the string elements one by one in the for loop above, you could use the approach in your example:
let result = ["Hello", "World"]
for myString in result {
// use each string element in some manner...
}
However, as you are using the array method joinWithSeparator(..), you should use, just as Leo writes in his comment above, this method directly on your array (and not their elements!)
let result = ["Hello", "World"]
outputLbl.text = result.joinWithSeparator("\n")
/* Hello\nWorld */
I think what you are doing here is trying to iterate through an array of string and then update a label that is in this case "outputLbl".Here you can do something like this
for i in result {
//result is array of strings.
// here i is individual element of result array
/* outputLbl.text = result[i].joinWithSeparator(“\n”)*/
//instead you can write
outputLbl.text = i.joinWithSeparator(“\n”)
}
The reason you are getting this error is as follows:
It seems you are confusing the type of i. The variable result is of type [String] which means it is an array of String types. By virtue of being an array, it must be subscripted with an Int, not a String. So something like result[0] or result[12] is valid, but something like result["hello"] is not valid. The variable i here is a String because it is a single element in an array of String types, which means that effectively, what you're trying to do by saying result[i] is something along the lines of result["hello"].
That having been said, the true solution to your problem is that the method joinWithSeparator(_:String) is not a String method but rather a Sequence type method. Which means it should be called on a Sequence like an object of type [String]. So what you should use is:
outputLbl.text = result.joinWithSeparator("\n")
What's going on here is the compiler is inferring i to be of type String since that's what result is. You should be more verbose in your naming conventions.
for specificString in result {
outputLbl1.text += "\n\(specifcString)"
}
EDITED for correctness.
Hey I have a question that I cant seem to get it work
I have closure type
public typealias VoidCompletionHandler = ()->Void
Then I create a optional variable
var favouritePropertyStateHandler:VoidCompletionHandler?
Then I call it
self.favouriteCellStateHandler?()
All works good
self.propertyModel?.favouritePropertyStateHandler = { self.favouriteStateChanged() }
Woks perfectly with fucntion type
func favouriteStateChanged()->Void
But why cant I just
self.propertyModel?.favouritePropertyStateHandler = self.favouriteStateChanged()
Types match - both are ?
()->Void
The error I get is
Cannot assign a value of type 'Void' ('aka '()') to a value of type 'VoidCopletionHanlder?'
Solved
self.propertyModel?.favouritePropertyStateHandler = self.favouriteStateChanged
However that creates another problem, how do I not cause eternal retain cycle? if I want self to be weak?
You're assigning the result from self.favouriteStateChanged(), not the function itself. Try
self.propertyModel?.favouritePropertyStateHandler = self.favouriteStateChanged
instead.
I just discovered a very strange behaviour. I have a class with a string property. In the setter of this property I compare the old value with the new value first and only change property if the values differ:
set
{
if ((object.ReferenceEquals(this.Identifier, value) != true))
{
this.Identifier = value;
this.RaisePropertyChanged("Identifier");
}
}
But this ReferenceEquals almost always returns false! Even if I call object.ReferenceEquals("test", "test") in Quick Watch I get false.
How is this possible?
That's because strings are immutable in C#:
The contents of a string object cannot
be changed after the object is
created, although the syntax makes it
appear as if you can do this.
Since you can't modify an existing string reference, there's no benefit in reusing them. The value passed to your property setter will always be a new string reference, except maybe if you do this.Identifier = this.Identifier;.
I'll try to clarify with an example:
string s = "Hello, "; // s contains a new string reference.
s += "world!"; // s now contains another string reference.