【问题标题】:Recursive, Variadic Template Function [duplicate]递归,可变参数模板函数
【发布时间】:2018-05-11 20:48:18
【问题描述】:

我知道我可以使用常规的可变参数函数来做到这一点,但我想使用模板来做到这一点。我的 (C++17) 编译器不同意。

#include <cstdint>

unsigned int fct(unsigned int k)
{
    return k;
}

template<std::size_t First, std::size_t... Other>
unsigned int fct(unsigned int k)
{
    return First * fct<Other...>(k);
}

int main(void)
{
    //const auto k = fct<3u, 5u, 7u>(2u);
    return 0;
}

上面的代码编译得很好。但是,如果我选择取消注释 k 的声明,编译将失败并显示以下报告:

foo.cpp: In function ‘int main()’:
foo.cpp:17:13: warning: unused variable ‘k’ [-Wunused-variable]
  const auto k = fct<3u, 5u, 7u>(2u);
             ^
foo.cpp: In instantiation of ‘unsigned int fct(unsigned int) [with     long unsigned int First = 7; long unsigned int ...Other = {}]’:
foo.cpp:11:30:   recursively required from ‘unsigned int fct(unsigned int) [with long unsigned int First = 5; long unsigned int ...Other = {7}]’
foo.cpp:11:30:   required from ‘unsigned int fct(unsigned int) [with long unsigned int First = 3; long unsigned int ...Other = {5, 7}]’
foo.cpp:17:35:   required from here
foo.cpp:11:30: error: no matching function for call to ‘fct<>(unsigned int&)’
  return First * fct<Other...>(k);
                 ~~~~~~~~~~~~~^~~
foo.cpp:9:14: note: candidate: template<long unsigned int First, long unsigned int ...Other> unsigned int fct(unsigned int)
 unsigned int fct(unsigned int k)
              ^~~
foo.cpp:9:14: note:   template argument deduction/substitution failed:
foo.cpp:11:30: note:   couldn't deduce template parameter ‘First’
  return First * fct<Other...>(k);
                 ~~~~~~~~~~~~~^~~

我怎样才能做到这一点?我认为创建一个非模板 fct() 就可以完成这项工作。

【问题讨论】:

    标签: c++ templates variadic-templates c++17 template-meta-programming


    【解决方案1】:

    应该是:

    template<std::size_t First>
    unsigned int fct(unsigned int k)
    {
        return First * k;
    }
    
    template<std::size_t First, std::size_t Second, std::size_t... Other>
    unsigned int fct(unsigned int k)
    {
        return First * fct<Second, Other...>(k);
    }
    

    wandbox 上查看。另一种选择是this,正如@chtz 在 cmets 中对答案所建议的那样。


    问题是以下函数不是函数模板:

    unsigned int fct(unsigned int k)
    {
        return k;
    }
    

    因此,当Other... 为空参数包时,您的调用相当于:

    return First * fct<>(k);
    

    但它与您的任何定义都不匹配。想一想:

    • 第一个函数不是模板函数,因此不匹配。
    • 第二个函数至少需要一个参数,因此不匹配。

    因此错误。

    【讨论】:

    • 容易多了:wandbox.org/permlink/Q76uWd6jDXkJnOo3 但是这个问题是重复的
    • @chtz 好点。我可以在答案中使用您的链接(有提及)吗?
    • 当然。 (由于评论限制,更多字符)
    • 谢谢你们俩,我将此线程标记为已解决。
    【解决方案2】:

    由于问题标记为 C++17,您可能想尝试新引入的fold expression (live)。

    #include <cstdint>
    #include <iostream>
    
    template <std::size_t... Args>
    auto fct(std::size_t k) noexcept {
      return (k * ... * Args);
    }
    
    int main() {
      std::cout << fct<>(1) << std::endl;
      std::cout << fct<2, 3>(1) << std::endl;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-23
      • 1970-01-01
      • 2013-08-04
      • 2012-05-17
      • 2016-12-11
      • 1970-01-01
      • 1970-01-01
      • 2011-06-29
      相关资源
      最近更新 更多