操作重载 C++在托管 C++项目

发布于 2024-11-04 01:45:13 字数 2108 浏览 2 评论 0原文

我有一个托管的 C++ dll,它与 C# GUI 进行交互。它工作正常,通信通过包装器,一切正常。 dll 内的代码都是用 C++ 编写的,但我无法让运算符重载工作,我打算使用它来对向量进行排序。我不知道我的代码中是否存在错误,或者它是否无法工作,因为它位于托管 C++ 项目中。

我已经尝试过 sort(it, it) 但它不起作用,因为运算符重载不起作用。我还尝试使用比较排序(it,it,less_than_second),但这也不起作用,因为我收到错误。我尝试了很多事情,但遇到了如下错误: - 排序只需要 2 个参数 - less_than_second_ 未声明的标识符

运算符重载不会产生错误。

这是我想要重载运算符 < 的移动类的代码:

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);
    }

I've a managed C++ dll which talks with a C# GUI. It works fine, the communication goes through a wrapper and it all works. The code inside the dll is all written in C++, but I can't get operator overloading working and im planning to use it for sorting vectors. I don't know if there's an error in my code or if it doesn't work because it's in a managed C++ project.

I've tried the sort(it, it) but it doesn't work because the operator overloading doesn't work. I've also tried to use the compare sort(it, it, less_than_second), and that also doesn't work because I get errors. I've tried alot of things and I got errors like:
- Sort only takes 2 arguments
- less_than_second_ undeclared identifier

The operator overloading doesn't produce errors.

Here's the code of the move class where I want to overload the operator <:

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);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

听风吹 2024-11-11 01:45:13

您的向量元素是 Move* (指针)。这是一个内置类型,您无法重新定义其运算符。并且 less_than_second 的签名错误,它不接受指针。

Your vector elements are Move* (a pointer). This is a built-in type, you can't redefine its operators. And less_than_second has the wrong signature, it doesn't accept pointers.

随风而去 2024-11-11 01:45:13

我非常确定您需要在类之外定义布尔运算符,比较两个对象不是类的隐式部分,它位于被比较对象的外部。

I am pretty sure you need to define your boolean operators outside of your class, comparing two objects is not an implicit part of a class, its external to the objects being compared.

昇り龍 2024-11-11 01:45:13

我认为您混淆了“超载”一词的两种不同使用方式。运算符重载意味着提供一种机制来作用于您的用户类型,就好像它是语言原始类型一样。函数重载意味着您​​有两个或多个具有相同名称但参数不同的函数。对于 C++ 中的每个运算符,您都有一个必须匹配的特定定义,同时您可以为派生类型的参数重载定义多个,它将​​包含相同数量的参数。

I think you are confusing two different ways that the word overloading is used. Operator overloading mean to provide mechanism to act on your user type as if it were a language primitive type. function overloading means that you have two or more functions with the same name but different parameters. For each operator is c++ you have a spesfic definition you must match while you can define multiples for parameter overloading of derived types it will allays contain the same number of parameters.

酒与心事 2024-11-11 01:45:13

我记得 C# 中 .NET 的逻辑和算术运算符重载需要您使用
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;

        }   

    }

互联网上还有其他几个例子

I recall that logical and arithmetic operator overloading for .NET in C# requires you use
reflection.emit at the intermediate language level. You can test for Type.IsPrimitive.

public delegate 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;

        }   

    }

There are several other examples on the internet

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文