我正在尝试使用递归来解决这个问题,如果我调用
decimal<0,0,1>();
我应该得到十进制数(在这种情况下为4)。
我正在尝试使用可变参数模板进行递归,但无法使其工作。
这是我的代码;
template<>
int decimal(){
return 0;
}
template<bool a,bool...pack>
int decimal(){
cout<<a<<"called"<<endl;
return a*2 + decimal<pack...>();
};
int main(int argc, char *argv[]){
cout<<decimal<0,0,1>()<<endl;
return 0;
}
解决这个问题的最佳方法是什么?
答案 0 :(得分:3)
template<typename = void>
int decimal(){
return 0;
}
template<bool a,bool...pack>
int decimal(){
cout<<a<<"called"<<endl;
return a + 2*decimal<pack...>();
};
问题在于递归情况,它希望能够调用decltype<>()
。这就是我在上面的第一个重载中定义的内容。你基本上可以忽略typename=void
,这是允许第一个编译的必要条件。
答案 1 :(得分:0)
一个可能的解决方案可以是使用constexpr函数(这样你就可以在适当的时候使用它值的运行时值),其中值是函数的参数。
像
这样的东西#include <iostream>
constexpr int decimal ()
{ return 0; }
template <typename T, typename ... packT>
constexpr int decimal (T const & a, packT ... pack)
{ return a*2 + decimal(pack...); }
int main(int argc, char *argv[])
{
constexpr int val { decimal(0, 0, 1) };
static_assert( val == 2, "!");
std::cout << val << std::endl;
return 0;
}
但我获得2而不是4。
你确定你的代码应该返回4吗?
- 编辑 -
正如aschepler所指出的,我的示例decimal()
模板函数返回&#34; eturns两倍于其参数的总和,而不是&#34;你想要什么。
好吧,0
,1
,true
和false
获得同样的结果;使用其他数字,您将获得不同的结果。
但您可以按如下方式修改decimal()
template <typename ... packT>
constexpr int decimal (bool a, packT ... pack)
{ return a*2 + decimal(pack...); }
避免这个问题。
答案 2 :(得分:0)
这是一个C ++ 14解决方案。除了std::integral_sequence
nad std::index_sequence
之外,它主要是C ++ 11,这两者在C ++ 11中都相对容易实现。
template<bool...bs>
using bools = std::integer_sequence<bool, bs...>;
template<std::uint64_t x>
using uint64 = std::integral_constant< std::uint64_t, x >;
template<std::size_t N>
constexpr uint64< ((std::uint64_t)1) << (std::uint64_t)N > bit{};
template<std::uint64_t... xs>
struct or_bits : uint64<0> {};
template<std::int64_t x0, std::int64_t... xs>
struct or_bits<x0, xs...> : uint64<x0 | or_bits<xs...>{} > {};
template<bool...bs, std::size_t...Is>
constexpr
uint64<
or_bits<
uint64<
bs?bit<Is>:std::uint64_t(0)
>{}...
>{}
>
from_binary( bools<bs...> bits, std::index_sequence<Is...> ) {
(void)bits; // suppress warning
return {};
}
template<bool...bs>
constexpr
auto from_binary( bools<bs...> bits={} )
-> decltype( from_binary( bits, std::make_index_sequence<sizeof...(bs)>{} ) )
{ return {}; }
它会将结果值生成为constexpr
转换为标量的类型。这在“编译时间”中比constexpr
函数稍强一些。
它假定第一位是列表中最重要的位。
您可以使用from_binary<1,0,1>()
或from_binary( bools<1,0,1>{} )
。
这种基于类型的编程风格导致代码在其签名中完成所有工作。这些机构由return {};
组成。