I thought that since f's argument is float - the float version of f will be called, but that's not the case. Why is it?
Thank you!
class A
{
public: virtual void f(int n)
{
cout<<"A"<<endl;
}
};
class B: public A
{
public: virtual void f(float f)
{
cout<<"B"<<endl;
}
};
int main()
{
A* ptr = new B;
ptr->f(6.66);
delete ptr;
}
Related
interfaces
abstract class Adder<T> {
T add(T a, T b);
}
abstract class Multiplier<T> {
T multiply(T a, T b);
}
abstract class Displayer<T> {
void display(T a);
}
An implementation that just happens to implement all three.
class IntImpl implements Adder<int>, Multiplier<int>, Displayer<int> {
#override
int add(int a, int b) {
return a + b;
}
#override
int multiply(int a, int b) {
return a * b;
}
#override
void display(int a) {
print('printing: ${a}');
}
}
A consumer that needs support for two of the interfaces.
But, I could not find how to declare such a thing.
class DisplayingAdder<T, K extends Adder<T>> {
final K engine;
DisplayingAdder(this.engine);
T addAndDisplay(T a, T b) {
final r = engine.add(a, b);
// How do I change DisplayingAdder class parametrization to make the next line functional?
// engine.display(r);
return r;
}
}
Code to exercise the above
void main() {
final e1 = IntImpl();
final da = DisplayingAdder(e1);
da.addAndDisplay(3,4);
}
Not sure what can be changed to allow the generic parameter to declare support for more than one abstract class.
You can't restrict a generic type to a type that implements multiple supertypes. The best you're going to have to do is separate engine into an object that implements Adder and an object that implements Displayer, then pass the instance of IntImpl to both. (This is more scalable anyway since it also allows you to pass different values to each if you wanted.)
class DisplayingAdder<T, A extends Adder<T>, D extends Displayer<T>> {
final A adder;
final D displayer;
DisplayingAdder(this.adder, this.displayer);
T addAndDisplay(T a, T b) {
final r = adder.add(a, b);
displayer.display(r);
return r;
}
}
void main() {
final e1 = IntImpl();
final da = DisplayingAdder(e1, e1);
da.addAndDisplay(3,4);
}
For this code:
module Module =
let func x y z = 0
[<EntryPoint>]
let main args =
func 1
func 1 1
0
Decompilation yields:
[CompilationMapping(SourceConstructFlags.Module)]
public static class Main
{
[CompilationMapping(SourceConstructFlags.Module)]
public static class Module
{
[Serializable]
internal sealed class main#30 : OptimizedClosures.FSharpFunc<object, object, int>
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[CompilerGenerated]
[DebuggerNonUserCode]
public int x;
[CompilerGenerated]
[DebuggerNonUserCode]
internal main#30(int x)
{
this.x = x;
}
public override int Invoke(object y, object z)
{
return func(x, y, z);
}
}
[Serializable]
internal sealed class main#31-1 : FSharpFunc<object, int>
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[CompilerGenerated]
[DebuggerNonUserCode]
public int x;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
[CompilerGenerated]
[DebuggerNonUserCode]
public int y;
[CompilerGenerated]
[DebuggerNonUserCode]
internal main#31-1(int x, int y)
{
this.x = x;
this.y = y;
}
public override int Invoke(object z)
{
return func(x, y, z);
}
}
[CompilationArgumentCounts(new int[]
{
1,
1,
1
})]
public static int func<a, b, c>(a x, b y, c z)
{
return 0;
}
[EntryPoint]
public static int main(string[] args)
{
int x = 1;
new main#30(x);
int x2 = 1;
int y = 1;
new main#31-1(x2, y);
return 0;
}
}
public static a Dump<a>(a arg00)
{
return arg00.Dump();
}
}
It generates a concrete type, that is generic parameters are provided at type definition. Why is not this done at the point of construction? I also noticed that types are generated in the module where call occurs, not where func is defined.
Having let func x y z = ... we need implementations of types to cover all possibilities:
FSharpFunc<T1,FSharpFunc<T2,T3,TReturn>>
FSharpFunc<T1,T2,FSharpFunc<T3,TReturn>>
FSharpFunc<T1,FSharpFunc<T2,FsharpFunc<T3,TReturn>>>
Compiler could generate all possible combinations in the same place, where function is defined, closing only for parameters with inferenced types.
You could argue that for the list of 7 args the set of types going to be quite large, but types like FSharpFunc<T1,T2,..,Tn, FSharpFunc<...>> are a mere optimazation. And FSharpFunc supports up to six generic types, then compiler has to switch to FSharpFun<T1,T2,T3,T4,T5,FSharp<...>>.
As pointed out by Fyodor it's not function creation that makes the compiler generating the hidden classes. The hidden classes are used to implement partial application.
In F# a partial application and lambdas are implemented as a compiler generated class that extends an abstract class. C# lambdas rely on delegates instead. IIRC Java and Scala use a similar technique to F# as JVM doesn't have delegates.
I suspect the F# compiler generates a class per partial application because it's simpler than collecting all partial applications and coalesce the identical ones.
It also helps the debuggability of F# programs as the name hints where the partial application was done: main#31-1 => In the main function at row 31. This name if included in logs or performance runs can help identifying what partial application is causing problems.
This comes at the cost of increasing the size of the F# assembly file as noted in a comment by Pavel.
Suppose I have something like this
void funct(int a ,int b)
{
std::cout << a+b ;//3+2=5
}
in C++ we could bind a value to parameter to b so the callback will only have to pass in one parameter. Can we do this in dart ?
int main()
{
auto f = std::bind(&funct,std::placeholders::_1,2); //pass b=2
f(3);
}
As mentioned in the comment below your question, you can accomplish this with a closure:
void funct(int a, int b) {
print(a + b);
}
void main() {
var f = (b) => funct(2, b);
f(3);
}
I know you can specify function types in formal arg list, but how would I do this for instance variables? I would like to do this:
class A<T> {
int compare(T a, T b);
}
where compare is a function variable with the appropriate type. I would like to be able to write:
A a = new A();
a.compare = ...
You can use typedef :
typedef Comparison<T> = int Function(T a, T b);
class A<T> {
Comparison<T> compare;
}
main() {
A a = new A<int>();
a.compare = (int a, int b) => a.compareTo(b);
print(a.compare(1, 2));
}
In addition to the Alexandre Ardhuin's answer, direct declaration, without typedef:
class A<T> {
late int Function(T a, T b) compare;
}
main() {
A<int> a = new A<int>();
a.compare = (int a, int b) => a.compareTo(b);
print(a.compare(1, 2));
}
MyStack()
{
Vector<Integer> v=new Vector<Integer>(10,2);
}
void push(int n)
{
v.addElement(n);
}
void pop()
{
if(v.isEmpty())
System.out.println("Stack underflow!");
else
System.out.println(v.elementAt(0));
}
void display()
{
for(int i=0;i<v.size();i++)
System.out.print(v.elementAt(i) +" ");
}
}
class StackDemo
{
public static void main(String args[])
{
Scanner in=new Scanner(System.in);
MyStack s=new MyStack();
int option=0;
do
{
System.out.println("1: Push\n2:Pop\n3:Display\n4:Quit");
System.out.println("Enter your option: ");
option=in.nextInt();
switch(option)
{
case 1:
{
System.out.println("Enter an integer:");
int n=in.nextInt();
s.push(n);break;
}
case 2:s.pop();break;
case 3:s.display();break;
}
}
while(option!=4);
}
}
// throws an error: variable v not found. Any help would be much appreciated.Thanks.
It looks like v is being created locally in your constructor instead of as a member of your class.
Try defining v as a class member and then simply assign it in your constructor.
class MyStack {
Vector<Integer> v;
public MyStack() {
v = new Vector<Integer>(10,2);
}
}
Or just assign it when you define it:
class MyStack {
Vector<Integer> v = new Vector<Integer>(10,2);
}
Check out the Java tutorial on class members.