简体   繁体   English

排除宏,我可以使用什么,如 C++ 中的内联 function

[英]Exclude Macro, What can I use like inline function in C++

I don't want to edit the common part of the source code repeatedly.我不想重复编辑源代码的公共部分。

So I separate the other parts with different functions as below.所以我将其他具有不同功能的部分分开如下。

/* Origin */
void MyClass::threadFunc_A()
{
    // many variables in this function
    ...

    // do something A
    ...
}

void MyClass::threadFunc_B()
{
    // many variables in this function
    ...

    // do something B
    ...
}

/* I wish */
void MyClass::threadFunc(type)
{
    // many variables
    int a, b;
    char c, d, e;
    ...
    string x, y, z;
    ...

    // case
    if (type == A) do_something_A();
    if (type == B) do_something_B();
    ...
    if (type == Z) do_something_Z();
}

void do_something_A()
{
   // using "many variables (a ~ z)" here
   a = 10;
   b = 20;
   ...
}

In the case of macro functions, I know that the code is built in when compiling, so that variables within the same range can be used.在宏函数的情况下,我知道代码是在编译时内置的,这样就可以使用相同范围内的变量。

However, if the do_something() function is lengthened, there is a limit to writing using the macro function.但是,如果do_something() function 被加长,则使用宏 function 写入存在限制。

Is there a way to write an inline function like 'I wish' in C++ 17 or higher?有没有办法在 C++ 17 或更高版本中编写像“我希望”这样的内联 function? (Except for putting A as a member variable of the class or making it a structure and passing it) (除了将 A 作为 class 的成员变量或使其成为结构并传递它)

No there is no way to do that.不,没有办法做到这一点。 C++ has lexical scoping. C++ 具有词法作用域。 What you want would be (at least partially) more like dynamic scoping.您想要的(至少部分)更像是动态范围。

The point of a function is that it separates some part of the logic into a self-contained block of code that can be reused. function 的要点在于,它将逻辑的某些部分分离为可以重用的独立代码块。 If you make the name resolution in the function dependent on the declarations at the call site, it becomes impossible to reason about the behavior of the function without also specifying the call site.如果您根据调用站点的声明在 function 中进行名称解析,则在不指定调用站点的情况下就无法推断 function 的行为。

Macros effectively do behave that way, but that is not a good thing.宏实际上确实以这种方式运行,但这不是一件好事。 It is one of the reasons to avoid them.这是避免它们的原因之一。

C++ does have templates, which allows making similar logic independent of concrete types in a function, but that still doesn't allow making name resolution dependent on the call site. C++ 确实有模板,它允许使类似的逻辑独立于 function 中的具体类型,但这仍然不允许使名称解析依赖于调用站点。

Write your functions so that they represent a part of the program logic that makes sense in itself.编写你的函数,使它们代表本身有意义的程序逻辑的一部分。 The function should take all variables to which it needs access as arguments, possibly with templated types, and if it needs to work on an unspecified number of arguments, possibly of different types, it can be a variadic function template. The function should take all variables to which it needs access as arguments, possibly with templated types, and if it needs to work on an unspecified number of arguments, possibly of different types, it can be a variadic function template. If there are many variables with similar meaning, consider putting them in an array or container or class combining them into one unit that makes sense in the program logic.如果有许多具有相似含义的变量,请考虑将它们放在一个数组或容器中,或者 class 将它们组合成一个在程序逻辑中有意义的单元。

I am not aware of a way to literally use a typename as a function parameter;我不知道有一种方法可以从字面上使用类型名作为 function 参数; except for specialized functions such as sizeof().除了 sizeof() 等特殊函数。

Some more normative ways to approach it would be:一些更规范的方法是:

  • Use an enum representing types, to pass to threadFunc() .使用表示类型的枚举传递给threadFunc()
  • Make a function in your class for each types, as overrides;在您的 class 中为每种类型创建一个 function 作为覆盖; and pass it a value of the type in question.并将其传递给相关类型的值。
  • Make a function parameter std::variant , and pass it a value of the type in question.创建一个 function 参数std::variant ,并将其传递给相关类型的值。 That way, you can inspect it to see which of the types it supports it is, using the ::index() property;这样,您可以使用::index()属性检查它以查看它支持的类型; or if you're using the Qt framework, QVariant() can get a dummy QVariant of the type with QVariant::type() that you can compare to, or a string as the typename, with QVariant::typename() .或者,如果您使用的是 Qt 框架,则 QVariant() 可以使用QVariant::type()获取可以与之比较的类型的虚拟 QVariant,或者使用QVariant::typename()获取作为类型名的字符串。
  • This SO?这样吗? purports to shows how to use a template to allow a typename as a function parameter: "https://stackoverflow.com/questions/937268/how-to-take-a-typename-as-a-parameter-in-a-function-c";旨在显示如何使用模板允许类型名作为 function 参数:“https://stackoverflow.com/questions/937268/how-to-take-a-typename-as-a-parameter-in-a-函数-c"; although the answers only have it to work for multiple return types.尽管答案仅适用于多种返回类型。

One downside of putting large blocks of code in C++ macros, is they can be hard to debug;将大块代码放在 C++ 宏中的一个缺点是它们很难调试; as they probably won't have syntax highlighting or in-editor syntax checking.因为他们可能没有语法高亮或编辑器内语法检查。 Also, the debugger may treat the whole block as a single line.此外,调试器可以将整个块视为单行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM