【问题标题】:Undefined number of arguments in C++ [duplicate]C ++中未定义的参数数量[重复]
【发布时间】:2013-05-02 11:55:37
【问题描述】:

我可以重载我的函数来做一些像 JavaScript 中那样有很多参数的事情吗? 例如:

function f()
{
  alert(arguments[0]);
}

f(4); // will alert 4 

我可以在 C++ 中做同样的事情吗?

【问题讨论】:

  • 所以你想用可变数量的参数调用你的函数?如果是这种情况,您始终可以使用可变参数函数,但就像这个页面所说的 en.cppreference.com/w/cpp/utility/variadic std::initializer_listvariadic templates 是类型安全且更易于使用的。
  • 抱歉,我的示例中有一个额外的冒号,导致无法正确编译。请查看我的新编辑以及demo

标签: c++ overloading variadic-functions


【解决方案1】:

您可以使用可变模板参数和元组:

#include <tuple>
#include <iostream>

template <class... Args>
void f(Args&&... args)
{
    auto arguments = std::make_tuple(std::forward<Args>(args)...);
    std::cout << std::get<0>(arguments);
}

void f() {} // for 0 arguments

int main()
{
    f(2, 4, 6, 8);
}

Live Demo

对于边界检查,请尝试以下操作:

#include <tuple>
#include <iostream>

template <class... T>
struct input
{
    std::tuple<T...> var;
    input(T&&... t) : var(std::forward<T>(t)...) {}

    template <std::size_t N, bool in_range = 0 <= N && N < std::tuple_size<decltype(var)>::value>
    auto get() -> typename std::tuple_element<in_range ? N : 0, std::tuple<T...>>::type
    {
        return std::get<in_range ? N : 0>(var);
    }
};

template <class... Args>
void f(Args&&... args)
{
    auto arguments = input<Args...>(std::forward<Args>(args)...);

    std::cout << arguments.template get<9>();
}

void f() {} // for 0 arguments

int main()
{
    f(2, 4, 6, 8);
}

更新:如果您需要第一个参数,那么您只需要一个通过将第一个参数与参数包分开来公开第一个参数的函数:

template<class Head, class... Tail>
void foo(Head&& head, Tail&&... tail);

如果这不令人满意(即您想获得第 n 个参数),您可以将参数解压缩到 std::tuple&lt;&gt; 并使用 std::get&lt;&gt; 检索元素:

template<class... Args>
void foo(Args&&... args)
{
    auto t = std::forward_as_tuple(std::forward<Args>(args)...);
    print(std::get<5>(t));
}

【讨论】:

  • @shafikYaghmour 你的问题有点含糊。你能把它缩小到一个特定的场景吗?
  • @ShafikYaghmour 您需要使用某种形式的循环来获取所有N 元素。您可以使用基于范围的 for 来执行此操作:for (auto a : tup) print( a )。您还可以通过模板参数使用编译时常量。
  • 有没有办法强制 args 成为单一的特定类型? (不必像这样滥用默认值:template&lt;class T = int, T... args) void f(T&amp;&amp;... args)
  • @Pharap 您可以使用 SFINAE:template&lt;class T, class...&gt; using first = T; template&lt;class... Args&gt; first&lt;void, typename std::enable_if&lt;std::is_same&lt;Args, int&gt;::value&gt;::type...&gt; f(Args&amp;&amp;...);Here's an example.
  • 谢谢 1234567890,我无法在任何地方找到合适的答案。诚然,我可能在搜索错误的术语。 SFINAE 确实是所有生命之谜的答案。
猜你喜欢
  • 2012-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-24
  • 2017-12-12
  • 2015-04-12
相关资源
最近更新 更多