I'm relatively new to C++, and I'm trying to take an array within a class, and set it equal to a passed in array.
public ref class Example {
array<float> ^ myarray1 = gcnew array<float>(3);
public:
Example(float^ myarray2) {
int i = 0;
while (i<3) {
myarray[i] = myarray2[i];
i += 1;
}
}
In the main function, the constructor is called as follows:
float myarray2[] = {1,2,3};
Example ^example1 = gcnew Example(*myarray2)
The errors I get is are as follows:
System::Single' has no default indexed property (class indexer)
expression must have pointer-to-object or handle-to-C++/CLI-array
type
Both of these errors are identified as happening where I am saying myarray[i] = myarray2[i].
I would greatly appreciate any help with solving this problem. I can't see where or how System::Single is getting pulled in as an error message. And, before it is suggested, I know I can get to work with setting myarray2 as a array float like myarray1, but I want it to work passing in myarray2 as float^ myarray2.
Since you say you're new to C++, let me point out that you're not writing classic C++ there. You're writing C++/CLI, which is a set of language extensions to C++ designed to interoperate with the CLI (.NET Framework). Because of this, the type float in your code is an alias for the type System::Single of the framework.
Regarding the indexer issue, the error messages pretty much spell out the cases in which you would be allowed to use an indexer:
System::Single' has no default indexed property (class indexer)
You could use an indexer if the type had a defined indexed property. System::Single, also known as float, doesn't happen to have one.
expression must have pointer-to-object type
You could use the indexer if the type was a non-void pointer type. You'd have to declare it like this:
Example(float* myarray2) {
In this case, myarray2[i] is equivalent to the expression *(myarray2 + i).
or handle-to-C++/CLI-array type
You could use the indexer if the type was a handle (^) to a C++/CLI array type. As you already know, you'd have to declare it like this:
Example(array<float> ^ myarray2) {
The bottom line is that, although you can treat a float* (pointer to float) like a C-style array of float (as a result of the rules of C and C++ about arrays and pointer arithmetic), these things simply do not apply to the float^ (handle to float) type (which is C++/CLI-specific).
Example(float^ myarray2)
That does not mean what you think it does. You are used to C language behavior, a float[] can automatically decay to a float* to the first element of the array. Somewhat unfortunately also carried forward into C++.
But not into C++/CLI, it is fundamentally unverifiable code. And responsible for a very large number of bugs and security problems. One core problem is that your constructor has no idea how many elements are stored in the array. You hard-coded "3" but if the caller passes an array that's smaller then Very Bad Things happen.
What it actually means is "reference to a boxed copy of a System::Single". The compiler tries to make sense of that, inevitably it starts to get very confused what you try to do next. Like using the [] operator, that requires the type to have an indexer. A float doesn't have one.
You need either:
Example(array<float>^ myarray2)
Which is safe and verifiable, you can't index the array out of bounds. And you don't have to hard-code "3" anymore, you can simply use myarray2->Length instead. And you don't (usually) have the copy the array anymore, simply assign myarray1. You'd call the constructor by passing gcnew array<float> { 1, 2, 3 }.
Or:
Example(float* myarray2)
Which works just like the way it does in C and C++. And required if you want to call the constructor with that float[]. Not verifiable, you need that magic "3". Do consider adding an extra argument to pass the array length.
Related
Apologies if the answer is obvious, but I don't get it. I have a function that accepts a FloatArray so I passed a Array<Float> to it but it rejects it! I thought FloatArray was just another way of creating Array<Float>. What's the difference?
Short answer: one is an array of primitives, the other an array of references to Float objects.
The difference is mostly hidden from you in Kotlin, so to explain it's probably best to go back to Java…
Java has nine basic types (if I've counted correctly). Eight of them hold a value directly: boolean, byte, short, char, int, long, float, and double — those are called ‘primitives’. The other type is a reference, which can point to an instance of an object or array.
Because there are cases when you need to pass one of those primitive values around as an object, Java also provides some objects which simply wrap a primitive value: java.lang.Boolean, java.lang.Byte, and so on. There's one for each primitive type.
Most code uses primitives directly, but sometimes it's handy to be able to pass an object reference. (For one thing, primitives are not nullable, so if you need to support a null, then you'll need an object reference. For another, generic code such as List and the other classes in the collections framework can handle only object references.)
However, object wrappers are less efficient, because each instance is a full object and takes a certain amount of memory (e.g. 16–32 bytes, depending on the Java runtime) — and that's in addition to the size of references to it (perhaps 8 bytes). The JVM caches commonly-used wrappers (e.g. true and false for booleans, and some small numbers), but for anything else you'll be creating new objects on the heap.
The wrappers are clearly distinguished from the primitive types — they're capitalised (and, in the case of Integer, spelled differently). In early versions of Java, they were not interchangeable; you needed to explicitly wrap (e.g. Int(someValue) and unwrap (e.g. someReference.intValue()) when needed. Java 5 added ‘autoboxing’, where in many cases the compiler would do that for you. This blurs the distinction a bit, but most of the time you still need to be aware of it.
One of the benefits of Kotlin is that it removes some of Java's unnecessary complexity. One of the ways it does this is by hiding that distinction almost completely. The Kotlin language has no primitives: everything looks like an object. However, for reasons of efficiency, compiled Kotlin uses primitives ‘under the hood’ where possible. For example:
var i: Int
That declares an Int value — which will be stored as a primitive field. However:
var i: Int?
That declares a reference to an integer wrapper. (That's because primitives are not nullable, and so a primitive can't store a null value.)
This is an implementation detail: most of the time, when you're writing Kotlin, you don't need to be aware of this. But the distinction is still there at runtime, and arrays are one of the rare times it becomes visible:
FloatArray is an array of primitives. It uses the minimum of memory, and interoperates with Java code that uses a float[] type.
Array<Float> is an array of references to Float objects. It's more flexible, and interoperates with Java code that uses a Float[] type.
So you can see that these are two different types, even though they do similar things.
If you're interoperating with existing code, that will control which one you should use. If you're writing new code, then you have the choice: FloatArray is likely to be more efficient and use less memory — but Array<Float> tends to be better supported in other code (which may be able to process all the relevant types just by accepting a generic Array, instead of having to support FloatArray and IntArray and LongArray and all the others).
Some information about arrays in Kotlin is available here: https://kotlinlang.org/docs/basic-types.html#primitive-type-arrays
Kotlin also has classes that represent arrays of primitive types without boxing overhead: ByteArray, ShortArray, IntArray, and so on. These classes have no inheritance relation to the Array class, but they have the same set of methods and properties.
So FloatArray and Array<Float> are not the same, the difference is that the first has no boxing overhead.
Look at how FloatArray is declared in the documentation. It is just another class, not related to the Array<T> class at all. Sure, they represent very similar things, with the difference being that one of them would box Float values, and the other doesn't, as explained by the other answer. But from the perspective of the type system, they are totally unrelated. It's as if I declared:
class A
class B
and tried to pass an instance of A to a parameter expecting a B.
There are builtin methods to convert between these types though:
floatArrayOf(1f,2f,3f).toTypedArray() // FloatArray to Array<Float>
arrayOf(1f,2f,3f).toFloatArray() // Array<Float> to FloatArray
It's just that there is no implicit conversion between them, because these are unrelated types, unlike if you have subclasses and superclasses for example.
I am trying to deserialize an array of JSON objects with GSON. So the simple call:
val arrayOfFoo = gson.fromJson(source, Array<Foo<*>>::class.java>)
should do the trick. But type erasure tells us, that Foo<*> does not exist at runtime, so the error "Only class literals are allowed on the left hand side of a class literal" pops up. Well, so the solution must be:
val arrayOfFoo = gson.fromJson<Array<Foo<*>>>(source, Array::class.java)
Unfortunatelly, now the Kotlin compiler magic - that turns arrays of Wrapper types into primitive arrays - can not be sure what to do and tells us:
"Array class literals require a class type. Please specify one in angle brackets".
But, wait: This is, what did not work a second ago. Using
Array<Foo>::class.java
does not work, too, since now the compiler tells us: "One type argument is expected for Foo".
I personally can not see a way to solve that. Is it impossible to give a class literal of a typed array, which's type also expects a type parameter?
You can get the array class from an array instance, for example either one of
arrayOf<Foo<*>>()::class.java
java.lang.reflect.Array.newInstance(Foo::class.java, 0)::class.java
The basic problem: You need to specify the type of your array. This is done using a TypeToken in Gson.
I hope this helps:
val listType = object : TypeToken<Array<String>>() {}.type
val json = """["1"]"""
val yourClassList :Array<String> = Gson().fromJson(json, listType)
print(yourClassList)
Note that for primitives, it is simpler: Gson().fromJson(json, IntArray::class.java)
I have several times used the expression anArray.[i] to access an element from an array.
but all the sudden when i try to make a very very simple function then i get an error.
let safeIndexIf anArray i =
anArray.[i]
I need to make a function that returns the ith element of the array so i thought that was an easy one but no...
The Error:
The operator 'expr.[idx]' has been used on an object of indeterminate type based on information prior to this program point. Consider adding further type constraints
Why is this not working? I dont know what the error means by that. All i know i have done something similar to this lots of times to access an element of anArray so why can't i this time?
It means the compilers type inference cannot determine that anArray is indeed an array.
The error message is suggesting you add a type annotation, you could do something like this to say that anArray is a generic array:
let safeIndexIf (anArray : array<'a>) i =
anArray.[i]
If you want to avoid type annotations you could try rewriting your function to use Array.item which has the same behaviour:
let safeIndexIf anArray i =
Array.item i anArray
I'm trying to create a sparse array in Swift. I'm not sure if the problem is in my declaration (no syntax errors detected) or possibly a bug in beta 2?
I am trying to declare an array of 24 class instances as optionals. I then can fill in slots of the array as necessary. Here is the declaration:
var usage = WaterUsage?[](count:24, repeatedValue:nil)
This gets through the Xcode 6 beta 2 compiler without error. The intention is to end up with an array of 24 "WaterUsage" classes all set to nil.
When I try to set an array element:
usage[hour] = usage
where hour is < 24 I get the error:
"WaterUsage doesn't have a member named subscript"
I've also tried using generics but that doesn't appear to work either.
I find the Swift syntax for using optionals in complex data structures is a little obscure and could use some advice here.
That way of defining the array is giving you an Optional array of Optional values ( WaterUsage?[]? ), which you have to unwrap before you can use. I think you want just the values to be optional: WaterUsage?[]. One way I've been able to do that is by using the generic Array syntax:
var usage: WaterUsage?[] = Array<WaterUsage?>(count:24, repeatedValue:nil)
usage[hour] = something
Another way is to force unwrapping of the return value of your initial declaration. I don't know why, but WaterUsage?[]() has an Optional return value.
var usage = (WaterUsage?[](count:24, repeatedValue:nil))!
usage[hour] = something
You're pretty close! When using the MemberType[] syntactic sugar for arrays, the way that you wrote it (WaterUsage?[]) actually declares the Array as Optional, as well as the values that it holds. In which case, to assign a value to an index you would need to unwrap the Array first by using:
usage![hour] = someWaterUsage
However, if you only want Optional members in the Array (and don't want the Array itself to be optional), then you can fall back to the standard Array declaration:
var usage = Array<WaterUsage?>(count:24, repeatedValue:nil)
edit:
I originally offered an alternate syntax as another solution as well:
var usage = (WaterUsage?)[](count:24, repeatedValue:nil)
...but in doing so, per #Nate's observations it then becomes the case that you need to use unwrapping twice to access the value at a specific index, for example:
usage[0]!!.someProperty
this is just a shot in the dark, but I think what may be happening in this case is not dissimilar at all to what OP originally tried with declaring the Array using WaterUsage?[]
that is, when using (WaterUsage?)[], perhaps it is seeing this declaration as an Array of Optional Tuples holding Optional WaterUsages, requiring us then to unwrap the member at the index twice before we can access its properties
interesting stuff!
That's an issue I still don't understand.
Sometimes I have to write:
NSString* myVariable;
myVariable = #"Hey!";
Then, for example I define a Structure "DemoStruct" and get an Variable that uses it. Lets say I have a Structure that has x and y vars from type double.
I want to pass this var to a method which then manipulates my var, and I want that this manipulation has effect on the context from which I passed the var to that method. So I need a pointer, right.
I pass it to the method like that:
[someObject someMethod:&myVarThatUsesTheStruct]
that method now looks like that:
- (void)someMethod:(DemoStruct*)myVar {
(*myVar).x += 10;
}
Before the call, the component x of the struct was lets say 1000. Now, 10 is added and it is 1010 after the method call.
But I really really hardly dont get it why I have to use the Asterisk * for myVar in the Method, since I say already in the Method Header that myVar is a POINTER to a DemoStruct. I just pass with &myVarThatUsesTheStruct the memory address.
Can someone explain why this is like it is?
As you say, myVar is a pointer. As such, myVar.x is not correct: it would by a field of a pointer, which has no sense in C/Objective-C.
If you want to access to the variable pointed to by a pointer, you have to add the asterisk: myVar is a pointer, *myVar is the variable pointed to by myVar.
Moreover, in your case, you can use a special construct of C by writing myVar->x, which is strictly equivalent to (*myVar).x.
All of this is standard C, not specific to Objective-C.
About your first example, you don't have to put an asterisk because you change the value of the pointer, not the value of the variable: myVariable is a pointer to an object which at declaration time is assigned the nil value. The next instruction (myVariable = #"Hey!") is an assignment of pointer values: #"Hey!" is a pointer to a NSString object. The value of this pointer (not the value of the pointed constant) is assigned to myVariable, which then points to the object #"Hey!".
Yes, this is diffucult to follow at first time...
* is the dereference operator. All that *myVar means is "Get me the thing that the pointer myVar points to". You need this distinction because you need to tell the computer that you want to change the thing that myVar points to, not myVar itself.
taken from the learning objective c link via the developers portal for iphone devs:
Objective-C supports both strong and weak typing for variables
containing objects. Strongly typed variables include the class name in
the variable type declaration. Weakly typed variables use the type id
for the object instead. Weakly typed variables are used frequently for
things such as collection classes, where the exact type of the objects
in a collection may be unknown. If you are used to using strongly
typed languages, you might think that the use of weakly typed
variables would cause problems, but they actually provide tremendous
flexibility and allow for much greater dynamism in Objective-C
programs.
The following example shows strongly and weakly typed variable
declarations:
MyClass *myObject1; // Strong typing
id myObject2; // Weak typing
Notice the * in the first declaration. In Objective-C, object
references are pointers. If this doesn’t make complete sense to you,
don’t worry—you don’t have to be an expert with pointers to be able to
start programming with Objective-C. You just have to remember to put
the * in front of the variable names for strongly-typed object
declarations. The id type implies a pointer.