1

How do I get this to work?

Is an int operating with a float causing the int to be implicitly promoted to a float (or double)?

      public static float [ ] operator / ( float [ ] a , int b )
        {
        float [ ] c = new float [ a . Count ( ) ];
        for ( int i = 0 ; i < a . Count ( ) ; i++ )
            {
            c[i] += a [ i ] / b;
            }
        return c;
        }

Error CS0563 One of the parameters of a binary operator must be the containing type

The compiler is barfing on the (/) on the operator declaration, not on the body.

Failed Scientist
  • 1,977
  • 3
  • 29
  • 48
dr d b karron
  • 187
  • 2
  • 16
  • Possible duplicate of [Generics and "One of the parameters of a binary operator must be the containing type" Error](http://stackoverflow.com/questions/6891776/generics-and-one-of-the-parameters-of-a-binary-operator-must-be-the-containing); see also [MSDN here](https://msdn.microsoft.com/en-us/library/zb1a95x1.aspx). – Ken Y-N Jun 13 '16 at 04:25
  • 1
    Completely unhelpful: it demonstrates how to elicit compiler error . – dr d b karron Jun 13 '16 at 04:44
  • 1
    I made an error with the wrong dup; as Keyu Gan points out, [this is a better description of the problem and solution](https://stackoverflow.com/questions/1687395/overloading-the-operator-to-add-two-arrays). – Ken Y-N Jun 13 '16 at 05:04
  • 1
    See my unhappy answer. The solution is worse than just hard coding the needed operation. – dr d b karron Jun 13 '16 at 05:29

3 Answers3

4

Operators must be declared inside a related class' body. That means your overloaded operator must contain a type of the class the new "/" function lies in.

However, there's no code space for array implementation (it is internalized). So unlike C++, it is impossible to achieve your goal without modification to types.

Here are several feasible ways:

  • Wrap a whole new class implementing a floating array (or list), define the operator in the new class.
  • Write a seperated function instead of an operator.
  • The best way, creating a more advanced wrapper class - see Jordao's answer in here, you only need to modify how the array is declared.
Community
  • 1
  • 1
Keyu Gan
  • 711
  • 5
  • 17
1

You may go with something like this

class FloatArray
{
    float[] arr;
    public FloatArray(float[] arr)
    {
        this.arr = arr;
    }
    public static float[] operator /(FloatArray a, int[] b)
    {
        var res = new float[a.arr.Length];
        for (int i = 0; i < a.arr.Length; i++)
        {
            res[i] = a.arr[i] / b[i];
        }
        return res;
    }
    public static implicit operator FloatArray(float[] arr)
    {
        return new FloatArray(arr);
    }
}

usage:

        var floats = new float[] { 20f, 30f };
        var ints = new int[] { 10, 6 };
        var result = (FloatArray)floats / ints;
Mike Tsayper
  • 1,686
  • 1
  • 17
  • 25
  • @drdbkarron because of memory copying and running Select. I have changed the code to remove those operations now it runs pretty fast – Mike Tsayper Jun 13 '16 at 05:57
0

Correct me if I am wrong. I think the implementation is wrong. There are little gaps in the build in math declarations, specifically implicit promotions of ints to floats.

If public is dangerous, consider private in a class.

I got close with these. The commented code block is not compiling but it should.

       public static Vertex operator / ( Vertex a , Vertex b )
            {
            Vertex c = new Vertex ( );
            c . x = a . x / b . x;
            c . y = a . y / b . y;
            c . z = a . z / b . z;
            return c;
            }
        public static Vertex operator / ( Vertex a , float b )
            {
            Vertex c = new Vertex ( );
            c . x = a . x / b;
            c . y = a . y / b;
            c . z = a . z / b;
            return c;
            }
        public static Vertex operator / ( Vertex a , int b )
            {
            Vertex c = new Vertex ( );
            c . x = a . x / b;
            c . y = a . y / b;
            c . z = a . z / b;
            return c;
            }
        public static Vertex operator + ( Vertex a , Vertex b )
            {
            Vertex c = new Vertex ( );
            c . x = a . x + b . x;
            c . y = a . y + b . y;
            c . z = a . z + b . z;
            return c;
            }
        public static implicit operator float[] ( Vertex a )
            {
            float [ ] f = new float [ 3 ];
            f [ 0 ] = a . x;
            f [ 1 ] = a . y;
            f [ 3 ] = a . z;
            return f;
            }


    //public dynamic float [ ] operator / ( float[] a, int b )
    //    {
    //    float [ ] c = new float [ a . Count ( ) ];
    //    for ( int i = 0 ; i < a . Count ( ) ; i++ )
    //        {
    //        c[i] += a [ i ] / b;
    //        }
    //    return c;
    //    }
    float [ ] NewCentroidf3 ( Vertex v0 , Vertex v1 )
        {
        float[] C = new float[3];

        C = v0 + v1;
        //C /= 2.0f;
        //C = C / 2; // would work if above worked.

        C [ 0 ] /= 2.0f;
        C [ 1 ] /= 2.0f;
        C [ 2 ] /= 2.0f;
        return C;
        }

We are considering adding "extension operators" to a hypothetical future version of C#, which would solve your problem. Straw poll: do any of you have AWESOME scenarios for this feature? The more awesome REALISTIC scenarios we can get, the more likely a feature is to be implemented some day. Send 'em my way; you can use the email link on my blog. – Eric Lippert Nov 6 '09 at 15:15

dr d b karron
  • 187
  • 2
  • 16
  • It is C#'s restriction that your "/" function must be related to the class it locates, which is `Vertex / something` or `something / Vertex` in this case. – Keyu Gan Jun 13 '16 at 05:50