首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >参数具有未知数据类型的变量函数

参数具有未知数据类型的变量函数
EN

Stack Overflow用户
提问于 2018-08-17 10:06:51
回答 3查看 1.3K关注 0票数 1

请允许我说,我知道这个问题不符合大多数惯例(如果有的话),但出于对编程语言(C++)的好奇和热爱,我还是要问这个问题。请随时纠正我与您的答案或评论以下。

问题:

“我们能否在C++中使各种函数接受多个(可能是以前未知的)数据类型的参数,以及如何实现它?”

示例:

JavaScript样品

代码语言:javascript
运行
复制
function buildArgs(... args) {
    let iterator = 0,
        length = args.length;

    for (iterator; iterator != length; iterator += 1) {
        let arg = args[iterator];
        build(arg)
    }
}

buildArgs(1); // Valid
buildArgs(1, "Hello"); // Valid
buildArgs(1, "Hello", null) // Valid

(假设) C++样本:

代码语言:javascript
运行
复制
template <class... Args, typename data>
inline void buildArgs(Args... args) {
    int iterator = 0,
        length = sizeof args;

    for (iterator; iterator != length; iterator += 1) {
        data arg = args[iterator];
        build(arg);
    }
}

buildArgs(1); // Valid
buildArgs(1, "Hello"); // Valid
buildArgs(1, "Hello", NULL); // Valid

从给出的示例中,被认为对函数buildArgs有效的参数可以是任意数据类型(charintstd::string等),而函数buildArgs可以接受任意数量的有效参数。

我已经对C++中的各种函数和模板做了一些小的研究,但是我所看到的还没有回答这个问题。

再次,我不能说这个功能的实用性,但我很想看看它是否可能。

链接:

·C:C中具有不同类型参数的变量函数中具有不同类型参数的变量函数

·在函数中接受所有类型的参数:接受所有类型作为函数中的参数

·C编程:编程/stdarg.h

·C++参考-参数包:pack

·C++引用-折叠表达式:https://en.cppreference.com/w/cpp/language/fold

·C:C++中可变的参数数?中可变参数数

结论:

感谢您抽出时间阅读我的问题,更感谢您的回答。

EN

回答 3

Stack Overflow用户

发布于 2018-08-17 10:33:01

参数包是当前C++实现该功能的方法:

代码语言:javascript
运行
复制
template<typename... Args> auto f(Args &&...args);

有了包,你可以做的不多,但仍然有:

将它们存储在元组或(如果可能的话)数组或initialization_list中:

代码语言:javascript
运行
复制
auto t = std::tuple(std::forward<Args>(args)...);
CommonType a[] = {args...};
std::set<int> mySet{args...};

使用它们作为函数参数(参见上面的元组构造)。C++中的一个包感知操作符是sizeof...

代码语言:javascript
运行
复制
std::size_t currentArity = sizeof...(Args);

三.折叠包:

代码语言:javascript
运行
复制
bool any = (args || ...);
(std::cout << ... << args);

set::set<int> myOtherSet;
(myOtherSet.insert(args), ...);

以此类推。

票数 2
EN

Stack Overflow用户

发布于 2018-08-17 10:31:45

对于C++11,它要复杂得多:实例化

代码语言:javascript
运行
复制
template <typename T>
void printArgs(T &&x)
{
    std::cout << std::forward<T>(x) << " - ";
}

template <typename FirstT, typename ...Args>
void printArgs(FirstT &&first, Args&&...remaining)
{
    printArgs(std::forward<FirstT>(first));
    printArgs(std::forward<Args>(remaining)...);
}

如您所见,您没有参数迭代器。相反,使用伪递归。

另外,一些奇怪的叫做完美转发的东西也应该被考虑进去。

在这里你可以看到提供调试信息的实例。

问题是:

“我们能否在C++中使各种函数接受多个(可能是以前未知的)数据类型的参数,以及如何实现它?

答案是肯定的。C++中的模板在使用时被实例化。因此,在默认情况下,它们可以处理任何类型,直到遇到某些内部问题为止,例如,某些功能对于特定类型不可用。

在上面的示例中,您可以定义自定义类型,而printArgs将失败,因为新类型没有operator<<(std::ostream &, const NewType &)。要解决这个问题,您必须简单地提供这样的操作符,printArgs将开始为新类型工作。

还有其他方法,如CRTP (奇怪的循环模板模式)等等。C++中的模板主题是相当长和复杂的。

票数 0
EN

Stack Overflow用户

发布于 2018-08-17 10:36:56

我们是否可以在C++中使用各种函数来接受多个数据类型(可能是以前未知的)的参数?

是。在标头<cstdarg>中有库工具使这更容易。

它们是:

  • va_start (启用对各种函数参数的访问),
  • va_arg (访问下一个变量函数参数),
  • va_copy (在C++11中引入,它复制了变量函数参数,
  • va_end (结束变量函数参数的遍历)和
  • va_list (它保存va_startva_argva_endva_copy所需的信息)。

此外,C、Go、C#、PHP、Java、JavaScript、Python、Perl 6支持此特性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51893037

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档