变量函数模板,其参数作为模板非类型传递

问题描述 投票:1回答:1

C ++ 17标准提到了一种特殊的可变参数函数模板

  • 不采用正常的函数参数,而是
  • 采用非类型模板参数,

f<200, 50, 6>() == 256

我想,这很奇怪,让我看看我是否可以自己编码。我的代码很优雅。然而,我优雅的代码无法编译,所以经过两个无效的时间后,我编写了这个丑陋的代码:

#include <iostream>

namespace {
    template<int A> constexpr int f() {return A;}
    template<int A, int B, int... C> constexpr int f() {
        if (sizeof...(C)) return A + f<B, C...>();
        else return A + B;
    }
}

int main() {
    int n = f<200, 50, 6>();
    std::cout << n << "\n";
    return 0;
}

这个丑陋的代码工作,它很有趣,因为它顺便教我sizeof...()。但这不可能是对的吗?

每当我尝试更简单的事情时,编译器就会喋喋不休,抱怨名称查找冲突或模板重新定义或类似的其他东西。

我的观念错了。我怀疑我错过了这一点。我错过了什么点,拜托?

参考

有关信息,在标准(草案here)中,引发我的问题的部分是sect。 5.13.8(第3和第4段)。但是,据我所知,挑衅是偶然的。我的问题不是标准本身。我的问题是关于变量的适当,优雅的使用,而不是。

非收集示例

如果你想要一个更优雅,非编译代码的例子,这里有一个:

namespace {
    template<> constexpr int f() {return 0;}
    template<int A, int... C> constexpr int f() {
        return A + f<C...>();
    }
}

阅读编译器的错误消息后,我理解为什么这个特定代码失败,所以这不是我的问题。相反,我的问题是

  • 如何像f<200, 50, 6>()这样的可变调用应该如何实现和
  • 我因此而忽略了C ++可变参数的概念。
c++ variadic-templates
1个回答
5
投票

C ++ 17编写函数的方法是

template<auto... Vals>
constexpr auto sum() noexcept(noexcept((Vals + ...)))
{
    return (Vals + ...);
}

其中template<auto... Vals>说我们有一个可变参数模板的值,而(Vals + ...)是一个fold expression,它将所有的值加在一起(外部()是制作有效折叠表达式所必需的)。

我使用了auto...,因此它不仅限于特定类型。如果需要,可以添加SFINAE以将模板限制为仅支持添加的类型,否则如果不能将参数包中的所有类型添加到一起,则只会出现编译器错误。

© www.soinside.com 2019 - 2024. All rights reserved.