I have the following Dart code:
void main() {
provide(1, 'A');
}
void provide<A>(A one, A two) {
print('one $one two $two');
}
In java the call to provide will give a compile time error as the two parameters should be both of type A. With java as soon as you pass an argument to a typed parameter that defines the type.
My understanding is that with Dart if I don't follow 'provide' with a type then the type is dynamic.
To get the above code to work correctly in dart I have to write:
void main() {
provide<int>(1, 'A');
}
void provide<A>(A one, A two) {
print('one $one two $two');
}
This will now give a compile type error as 'A' is not an int.
This however is error prone as the user is likely to forget to add the type when callng provide.
Is there anyway I can make calls to the provide method type safe without having to write provide<int>(....
I've trivialised the example, the aim is to make a call to a method such as :
void provide(Token<T> token, T value);
If T is not the correct type then the user should get a compile error.
Related
I'm a bit confused about the implications of the using declaration. The keyword implies that a new type is merely declared. This would allow for incomplete types. However, in some cases it is also a definition, no? Compare the following code:
#include <variant>
#include <iostream>
struct box;
using val = std::variant<std::monostate, box, int, char>;
struct box
{
int a;
long b;
double c;
box(std::initializer_list<val>) {
}
};
int main()
{
std::cout << sizeof(val) << std::endl;
}
In this case I'm defining val to be some instantiation of variant. Is this undefined behaviour? If the using-declaration is in fact a declaration and not a definition, incomplete types such as box would be allowed to instantiate the variant type. However, if it is also a definition, it would be UB no?
For the record, both gcc and clang both create "32" as output.
Since you've not included language-lawyer, I'm attempting a non-lawyer answer.
Why should that be UB?
With a using delcaration, you're just providing a synonym for std::variant<whatever>. That doesn't require an instantiation of the object, nor of the class std::variant, pretty much like a function declaration with a parameter of that class doesn't require it:
void f(val); // just fine
The problem would occur as soon as you give to that function a definition (if val is still incomplete because box is still incomplete):
void f(val) {}
But it's enough just to change val to val& for allowing a definition,
void f(val&) {}
because the compiler doesn't need to know anything else of val than its name.
Furthermore, and here I'm really inventing, "incomplete type" means that some definition is lacking at the point it's needed, so I expect you should discover such an issue at compile/link time, and not by being hit by UB. As in, how can the compiler and linker even finish their job succesfully if a definition to do something wasn't found?
I have a dart method that takes a generic type.
At the top of the method I want to print the name of the type that was passed as T, is this possible?
eg
void myMethod<T> () {
print("myMethod called with type="+????);
}
If myMethod is called with myMethod() it would print "myMethod called with type=String".
Yes and no.
You can write
void myMethod<T> () {
print("myMethod called with type=$T");
}
The only problem is that the Dart libraries don't promise that a Type object (which is what T evaluates to) will have a toString which returns the source name of the type in the original program.
It generally does give that string, but if you compile for the web with "minification", it might not keep the source names available.
There is also no promise that the toString of Type won't change in the future, since it is entirely unspecified.
Asking for help for the SOS extension command !BPMD in Windbg (i.e. typing !help BPMD) results in a text which contains, among other things, a description on how to break into generecally typed methods. This reads as follows:
!BPMD works equally well with generic types. Adding a breakpoint on a generic
type sets breakpoints on all already JIT-ted generic methods and sets a pending
breakpoint for any instantiation that will be JIT-ted in the future.
Example for generics:
Given the following two classes:
class G3<T1, T2, T3>
{
...
public void F(T1 p1, T2 p2, T3 p3)
{ ... }
}
public class G1<T> {
// static method
static public void G<W>(W w)
{ ... }
}
One would issue the following commands to set breapoints on G3.F() and
G1.G():
!bpmd myapp.exe G3`3.F
!bpmd myapp.exe G1`1.G
What I fail to understand here is the syntax used in the last two lines. What does the apostrophe (`) mean, and what is the meaning of the tho integers involved (the ones to the right of the apostrophe)? Are these codes related to the type (public void and static public void) of the methods, or do they refer to the number of template arguments? In case the first guess is true, where would I find a list of possible types?
The backtick symbol is the syntax for specifying a generic type in IL. The number after the backtick is the number of generic parameters.
I have a piece of software in which there is a function ie:
void function_name(structure_t *param1, void *param2){code....}
I am trying to create a function prototype for this function so it can be linked to another function that occurs before it. I have tried the below line with no success, it does not want to compile.
void function_name(structure_t, void);
I have this line below the associated structure but my guess is the problem is related to the void. The function itself takes the void *param2, which to be honest, confuses me but it works.
The compiler gives the error message: "'void' must be the only parameter"
The Function declaration is missing the * to define the arguments as pointers!
void function_name(structure_t *, void *);
I can't understand how to define default values for functions in my library. Default values tend to be ignored and I get "wrong parameters count" error message.
Here is my example. I created simple test library experts\libraries\test.mq4:
void test(int i = 0) // Note the default value for "i"
{
}
Then I created .mqh file as experts\include\test.mqh:
#import "test.ex4"
void test(int i = 0); // Note the default value for "i"
#import
Now I create simple expert "experts\simpletest.mq4":
#include <test.mqh>
int start()
{
// Should be able to call test() function without providing any arguments,
// because it has default value.
// If I change this line to test(0), everything compiles correctly
test(); // Causes "wrong parameters count" compilation error
return(0);
}
And I get the following error for test() function call:
')' - wrong parameters count
If I change this function call to test(0), everything compiles, but I should be able to call test() function without providing any parameters, because I have default value for first parameter in .mqh file, like this: void test(int i = 0);
Why it doesn't use the default value?
I search google for any clue, but can't find any references about this problem. Anybody knows?
This is not possible as stated in the MQL Documentation:
MQL4-library functions imported within other modules cannot have parameters initialized by default values.