Перегрузка операций C ++ в управляемом проекте C ++ - PullRequest
0 голосов
/ 28 апреля 2011

У меня есть управляемая C ++ dll, которая взаимодействует с C # GUI.Работает нормально, общение проходит через обертку и все работает.Код внутри dll полностью написан на C ++, но я не могу заставить работать перегрузку операторов, и я планирую использовать его для сортировки векторов.Я не знаю, есть ли ошибка в моем коде или она не работает, потому что это в управляемом проекте C ++.

Я пробовал сортировку (это, это), но она не работает, потому что перегрузка оператора не работает.Я также пытался использовать сортировку сравнения (it, it, less_than_second), и это также не работает, потому что я получаю ошибки.Я перепробовал много вещей, и я получил ошибки, такие как: - Сортировка принимает только 2 аргумента - less_than_second_ необъявленный идентификатор

Перегрузка оператора не приводит к ошибкам.

Вот код перемещениякласс, где я хочу перегрузить оператор <: </p>

public class Move
{

public:
    friend bool operator < (const Move &firstMove, const Move &secondMove)
    {
        return (firstMove.score < secondMove.score);
    }
    bool operator<(const Move& b) {
     return this->score < b.score;
    }
    int positionFrom;
    int positionTo;
    int tileFrom;
    int score;
    bool isJumpMove;
    Move(void);
    Move(int to);
    Move(int from, int to, bool isJumpMove);
    Move(int from, int to, int tileFrom, bool isJumpMove);


};

Testcode in a function of another class.

Move* move1 = new Move();
        move1->score = 2;
        Move* move2 = new Move();
        move2->score = 1;
        Move* move3 = new Move();
        move3->score = 0;
        Move* move4 = new Move();
        move4->score = 4;

        if(move1 < move2)
        {
            Console::WriteLine("2 is bigger than 1");
        }
        else
        {
            Console::WriteLine("1 is bigger than  2");
        }

        vector<Move*> vectorList;
        vectorList.push_back(move1);
        vectorList.push_back(move2);
        vectorList.push_back(move3);
        vectorList.push_back(move4);

        for (int i=0; i<vectorList.size(); i++) {
         Console::WriteLine(vectorList[i]->score);
        }
        sort (vectorList.begin(), vectorList.end() );
        sort (vectorList.begin(), vectorList.end(), less_than_second);
        for (int i=0; i<vectorList.size(); i++) {
         Console::WriteLine(vectorList[i]->score);
        }
the compare function ( it's in the cpp file of another class )

inline bool less_than_second( Move &move1,Move &move2){
        return (move1.score < move2.score);
    }

Ответы [ 4 ]

2 голосов
/ 28 апреля 2011

Ваши векторные элементы Move* (указатель). Это встроенный тип, вы не можете переопределить его операторы. И less_than_second имеет неправильную подпись, он не принимает указатели.

1 голос
/ 28 апреля 2011

Я почти уверен, что вам нужно определить ваши логические операторы вне вашего класса, сравнение двух объектов не является неявной частью класса, оно является внешним по отношению к сравниваемым объектам.

0 голосов
/ 28 апреля 2011

Напоминаю, что перегрузка логических и арифметических операторов для .NET в C # требует использования Reflection.emit на промежуточном уровне языка. Вы можете проверить на Type.IsPrimitive.

открытый делегат TResult BinaryOperator

      TResult>(TLeft left, TRight right);



/// <summary>

/// See Stepanov and McJones BinaryOperator

/// </summary>

/// <typeparam name="TLeft"></typeparam>

/// <typeparam name="TRight"></typeparam>

/// <typeparam name="TResult"></typeparam>

/// <typeparam name="TOwner"></typeparam>

static class GenericOperatorFactory<TLeft, TRight, TResult, TOwner>

{

    private static BinaryOperator<TLeft, TRight, TResult> add;

    private static BinaryOperator<TLeft, TRight, TResult> sub;

    private static BinaryOperator<TLeft, TRight, TResult> mul;

    private static BinaryOperator<TLeft, TRight, TResult> div;



    public static BinaryOperator<TLeft, TRight, TResult> Add

    {

        get

        {

            if (add == null)

            {

                // For debugging

                Console.WriteLine("Creating Add delegate for:\nTLeft = {0}\n" +

                "TRight = {1}\nTResult = {2}\nTOwner = {3}", 

                typeof(TLeft), typeof(TRight), typeof(TResult), typeof(TOwner));



                DynamicMethod method = new DynamicMethod(

                    "op_Addition:" + typeof(TLeft).ToString() + ":" + typeof(TRight).ToString() + ":" + typeof(TResult).ToString() + ":" + typeof(TOwner).ToString(),

                    typeof(TLeft),

                    new Type[] { typeof(TLeft), typeof(TRight) },

                    typeof(TOwner)

                );



                ILGenerator generator = method.GetILGenerator();



                generator.Emit(OpCodes.Ldarg_0);

                generator.Emit(OpCodes.Ldarg_1);



                if (typeof(TLeft).IsPrimitive)

                {

                    Console.WriteLine("Adding primitives");

                    generator.Emit(OpCodes.Add);

                }

                else

                {

                    Console.WriteLine("Adding non-primitives");

                    MethodInfo info = typeof(TLeft).GetMethod(

                        "op_Addition",

                        new Type[] { typeof(TLeft), typeof(TRight) },

                        null

                    );



                    generator.EmitCall(OpCodes.Call, info, null);

                }



                generator.Emit(OpCodes.Ret);



                Console.WriteLine("Method name = " + method.Name);



                add = (BinaryOperator<TLeft, TRight, TResult>)method.CreateDelegate(typeof(BinaryOperator<TLeft, TRight, TResult>));

            }



            return add;

        }   

    }

В интернете есть еще несколько примеров

0 голосов
/ 28 апреля 2011

Я думаю, что вы путаете два разных способа использования слова перегрузка.Перегрузка оператора означает предоставление механизма для работы с вашим типом пользователя, как если бы он был языковым примитивным типом.Перегрузка функций означает, что у вас есть две или более функции с одинаковым именем, но разными параметрами.Для каждого оператора c ++ у вас есть специальное определение, которое вы должны сопоставить, в то время как вы можете определить кратные значения для перегрузки параметров производных типов, которые будут содержать одинаковое количество параметров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...