本文介绍了基于传递的int的运算符重载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用C ++实现自己的编程语言.

I am trying to implement my own programing language in C++.

在我的语言中发生错误时(例如,在词法分析过程中),主函数将抛出异常以捕获该异常,然后打印其消息.

When an error occours in my language (for example, during lexical analysis), an exception is thrown to be catched by the main function which then prints its message.

异常可以是不同的类型:SyntaxErrorFunctionError等等,它们都基于Error类,因此即使它们属于不同类型,也都可以捕获它们.

The exception can be of different types: either SyntaxError, or FunctionError and so on, all based on the Error class so that they can all be catched even being of different types.

无论如何,每个错误子类都可以生成不同类型的错误,每个错误类都需要有关抛出错误以构造其错误消息时发生的情况的不同信息.

Each sub class of errors anyway can generate different types of error, each one requiring different informations on what was happening when the error was thrown to construct its error message.

为解决此问题,我考虑了以下解决方案:

To solve this problem, I accounted for this solution:

//Error contains a public "message" attribute of type std::string, and a constructor to initialize that string

class SyntaxError: public Error {
    SyntaxError(int code, void* infos[]) {
        Error("SintaxError: ");
        switch (code) {
            //each sub error has its own code and based on that the function assumes the pointers to the objects needed to construct the error message are stored in the infos array
            case 1: //Unfinished string
            //it assumes the line at which the error is thrown is stored in the first position of the passed array
                message += "Unfinished string (at line " + std::to_string(*((int*) infos[0])) + ").";
            case 2: //Malformed number
                ...
            ... //other errors, each one assuming in the infos array are stored pointers to different types of objects
        }
    }
};

但是,当您要引发错误时,这需要进行很好的设置(因为您必须确定要引发的错误类型,并根据该错误类型创建指向所需信息的指针数组),并且在构造函数本身:我什至无法命名所需的对象,因为我无法在switch语句中声明它们,而应该在函数开始时声明所有它们.

This however requires a great setup when you want to throw the error (because you must estabilish what type of error you want to throw and based on that create an array of pointers to the informations required) and it's also pretty messy in the constructor itself: I can't even name the objects required because I can't declare them in the switch statement and I should declare all of them at the start of the function.

因此,我想提出另一种解决方案:使用所需的对象重载构造函数,以便当我要抛出未完成的字符串错误时,我只需要传递int,行和当我想抛出一个格式错误的数字错误时,我必须传递一个int 一个string(格式错误的数字),依此类推.

So I tought to another solution: overloading the constructor with the objects needed, so that when I want to throw a unfinished string error I just have to pass an int, the line, and when I want to throw a malformed number error I have to pass an int and a string (the malformed number), and so on.

重点是,将出现需要相同数量和类型信息的错误,例如,字符串中使用的无效转义序列错误,例如,将需要int (行)和string(使用的转义序列),就像格式错误的数字重载一样,我不知道如何区分它们.

The point is, there will be errors requiring the same number, and types, of informations, like, a invalid escape sequence used in string error, for an example, would require an int (the line), and a string (the escape sequence used), just like the malformed number overload, and I don't know how to differentiate them.

那么,有没有一种方法可以告诉编译器基于我传递给该函数的整数来调用具有相同参数列表的不同函数之间的哪个函数?

So, is there a way to tell the compiler which function between different functions with the same parameter list to call based on an integer I pass to the function?

推荐答案

简短答案

您正在寻找的技术称为标签分发.

The technique you are looking for is named tag dispatching.

好答案

使用int(和std::integral_constant s调度请求?)很难理解,我宁愿定义一个枚举类并使用模板方法.

Using ints (and std::integral_constants to dispatch the request?) is somehow hard to read, I'd rather define an enum class and use a template method.

例如:

enum class Tag { FOO, BAR };

那么您主要有两个选择:

Then you have mainly two choices:

  • 模板方法和完整的专业知识:

  • Template method and full specializations:

template<Tag>
void myMethod(int arg1, char arg2);

template<>
void myMethod<Tag::FOO>(int arg1, char arg2) {}

template<>
void myMethod<Tag::BAR>(int arg1, char arg2) {}

以以下方式调用:

myMethod<Tag::FOO>(42, 'c');

  • 标签分配:

  • Tag dispatching:

    void myMethod(tag<Tag::FOO>, int arg1, char arg2) {}
    
    void myMethod(tag<Tag::BAR>, int arg1, char arg2) {}
    

    以以下方式调用:

    myMethod(tag<FOO>{}, 42, 'c');
    

    在这种情况下,您必须在某处定义tag结构.例如:

    In this case, you have to define the tag struct somewhere. As an example:

    template<Tag>
    struct tag {};
    

  • 这篇关于基于传递的int的运算符重载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    10-28 09:43