c++ - c\c++ - 以 union 作为参数以满足特定要求的函数

标签 c++ c arguments compatibility unions

我正在设计库来为一台设备提供功能。该设备有一些共同的操作,但有不同的算法来完成这些操作。我想要一个函数原型(prototype)用于一个特定的操作,而不是一堆,而不是:

Alg1_Foo();
Alg2_Foo();
...

我想要这个:

Foo(alg);

但我不想将 alg 作为单独的参数传递,因为即使没有它,函数也会有很多参数,它们将有用于设备识别和/或授权的参数,in argument,out argument(至少其中之一),所以我认为将 alg 添加为单独的参数会很烦人。

所以我的想法是提供这样的解决方案:

Foo(const SomeUnion& some_union);

地点:

union SomeUnion {
  AlgId alg_id;
  alg1::SomeStruct alg1_some_struct;
  alg2::SomeStruct alg2_some_struct;

  SomeUnion(alg1::SomeStruct some_struct) { alg1_some_struct = some_struct; };
  SomeUnion(alg2::SomeStruct some_struct) { alg2_some_struct = some_struct; };
};

特定算法的结构将是这样的:

namespace alg1 {
  struct SomeStruct {
    static const AlgId alg_id = ALG1;
    . . .
  };
}

所以如果想执行 alg1,我们将适当的结构传递给 Foo,它在 C++ 中工作,比如

alg1::SomeStruct a;
Foo(a);

但我希望我的库保持纯 C 的可能性。当然我需要:

  1. 删除引用并用指针替换它们;

  2. 删除命名空间(我们仍然可以借助结构来模拟它们(此线程可能对那些感兴趣的人有所帮助:Namespaces in C));

  3. 将定义结构的 C++ 风格替换为 C 中的结构,并在标签命名空间中定义名称 (typedef struct tagStruct {...} Struct;);

  4. 从内部结构和 union 中删除函数。

但是虽然我不明白是否有可能通过维护 C 来完成我想做的事情......你明白了吗?或者将 alg_id 作为单独的参数传递而不用担心 union 和结构(但我想尽可能避免它)是否更简单?

最佳答案

对我来说,这似乎是一个典型的案例,有人试图以“错误的方式”解决问题。

如果函数有“很多参数”,那么使用 struct 就可以了。但是在这样的 struct 中隐藏“你实际调用的函数”,然后在 union 中有多个 struct 的变体,现在我们试图在一个函数中塞入太多内容。开始拆分函数,使其只需要一个 struct - 删除你的 union 作为参数 - 这是错误的。 [我曾使用过与此类似的代码 - 有可能偷偷加入一些做错事的代码并导致一些难以发现的错误,因为你将错误类型的 union 参数传递给了功能使这确实是一个糟糕的解决方案]。如果您将错误类型的结构传递给普通函数,那么编译器会告诉您。如果你填写了一个 union 的错误部分,使用结构“正确”部分的代码将得到“奇怪”的数据[很可能是未定义的行为] - 这种类型的错误可能很难找到。

所以是的,拆分你的功能,删除 union !

编辑: 如果您希望拥有一个简单且一致的界面,我想到的一个建议是您有一个工厂函数,您将 alg_id 传递给该函数,该函数返回一个指向相关函数的函数指针。不幸的是,如果每个函数的接口(interface)都像我建议的那样,是不同的结构,那么您仍然有可能将数据结构和函数混合在一起,但它确实减少了“已​​发布函数”的数量——事实上,这些函数根本不需要在提供它们的模块 [库甚至目标文件] 之外可见。

关于c++ - c\c++ - 以 union 作为参数以满足特定要求的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15168563/

相关文章:

c++ - 在进入 SGEMM 时,参数编号 8 具有非法值

c - 第一次使用 select(),可能是一个基本问题?

objective-c - 如何将可变数量的参数从带有可变数量参数的 method1 传递给 method2?

c++ - 将变量用作 emplace_back 的参数后可以使用变量吗?

c++ - 为什么#include 这个文件不止一次出现链接器错误?

c - 从丢失的 TCP 连接中恢复传输

python - 从 python subprocess.call 调用 rsync

python - python函数的参数列表

c++ - 了解使用 boost::asio 和 boost::thread 时的内存泄漏

c++ - §14/2 中的 "last component"一词的含义是什么?