【问题标题】:Limit the number of parameters in a variadic template parameter pack限制可变参数模板参数包中的参数数量
【发布时间】:2016-09-21 15:47:33
【问题描述】:

我有一个模板函数,它接受可变数量的参数。由于您不能强制参数为某种类型,我至少希望强制参数的数量不要高于编译时确定的数量(例如 10)。

如果带有参数包的模板函数的参数数量高于编译时确定的值,是否可以使编译器出错?

template <class ...Args>
void setRequestArguments(const Args&... args)
{
    const std::vector<QGenericArgument> vec = { args... };
    qDebug() << sizeof...(args);
    // Do stuff...
    // for (unsigned i = 0; i < vec.size(); ++i) {
    //     qDebug() << vec[i].name();
    // }
}

我想用它作为一个通用容器,用于 QMetaObject::invokeMethod 包装函数中的所有参数。

【问题讨论】:

  • 可以将参数限制为某种类型。你想得到这个答案吗?您是否要求参数完全是 T 或可转换为 T 的东西?
  • @bolov 是的,拜托,这将非常有用!我会 +1
  • 我创建了一个新帖子,正是这样:stackoverflow.com/questions/39659127/…
  • @bolov 很棒的帖子,谢谢!

标签: c++ templates c++11 variadic-templates variadic-functions


【解决方案1】:

要使函数在参数过多时不可调用,可以使用 sfinae 约束函数。这样,如果有另一个接受更多参数的重载,编译器将能够选择正确的重载。

一个简单的std::enable_if 就足够了:

template <class ...Args, std::enable_if_t<(sizeof...(Args) <= 10)>* = nullptr>
void setRequestArguments(const Args&... args)
{
    const std::vector<QGenericArgument> vec = {args... };
}

为了可读性,您可以将约束放在函数的尾随返回类型中:

template <class ...Args>
auto setRequestArguments(const Args&... args) -> std::enable_if_t<(sizeof...(args) <= 10)>
{
    const std::vector<QGenericArgument> vec = {args... };
}

这是使用 requires 和简洁模板语法的 C++20 更新版本:

auto setRequestArguments(const auto&... args) requires (sizeof...(args) <= 10) -> void {
    const std::vector<QGenericArgument> vec = {args... };
}

【讨论】:

  • 这确实是一种使用 SFINAE 的有趣方式 :)
【解决方案2】:

如果带有参数包的模板函数的参数数量高于编译时确定的值,是否可能使编译器出错?

是的,使用static_assert

template <class ...Args>
void setRequestArguments(const Args&... args)
{
    static_assert(sizeof...(args) <= 10, "You can't have more than 10 arguments!");
    //Stuff...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-01
    • 2017-08-04
    • 2016-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    相关资源
    最近更新 更多