[英]How to specialize template pack?
I have the following code, which tries to convert a binary number (passed as a list of booleans, least-significant first, variable lenght) into a decimal number: 我有以下代码,该代码尝试将二进制数(作为布尔值列表(最低有效,第一个,变量长度)传递)转换为十进制数:
#include <iostream>
using namespace std;
template<typename T>
int bin_to_dec(int multi, T first) {
cout<<"mutli"<<multi<<endl;
return first?multi:0;
}
template<typename T, typename... Args>
int bin_to_dec(int multi, T first, Args... args) {
cout<<"mutli"<<multi<<endl;
return (first?multi:0) + adder(multi*2, args...);
}
template<typename T, typename... Args>
int bin_to_dec(T first, Args... args) {
cout<<"mutli"<<1<<endl;
return (first?1:0) + adder(2, args...);
}
int main()
{
cout<<bin_to_dec(true, true, false, true)<<endl;
}
It works quite well, but I would like to make it possible only for booleans, so when I try something like bin_to_dec(1,2,3) it should not compile. 它工作得很好,但我只想让布尔值成为可能,所以当我尝试类似bin_to_dec(1,2,3)之类的东西时,不应编译。 I was trying to use something like 我正在尝试使用类似
template<bool First, bool... Bools>
but I can't figure out how to go further with that. 但是我不知道该怎么做。 Any ideas? 有任何想法吗?
The obvious approach is to remove the function from the overload set for all template arguments but bool
: 一种明显的方法是从所有模板参数( bool
的重载集中删除该函数:
template <typename... T>
std::enable_if_t<variadic_and(std::is_same<T, bool>::value...), int>
bin_to_dec(T... bits) {
// probably delegate to differently named functions as an implementation detail
// ...
}
variadic_and()
would be a constexpr
function returning true
if all its arguments are true
: variadic_and()
将是一个constexpr
函数返回true
,如果其所有参数都true
:
constexpr bool variadic_and() { return true; }
template <typename... T>
constexpr bool variadic_and(bool v, T... vs) {
return v && variadic_and(vs...);
}
With C++17 variadic_and()
would be necessary as parameter packs can be expanded with an operator. 使用C ++ 17时,必须使用variadic_and()
,因为可以使用运算符扩展参数包。 For example, the implementation of variadic_and()
could look like this: 例如, variadic_and()
的实现可能如下所示:
template <typename... T>
constexpr bool variadic_and(T... vs) { return (vs && ...); }
The same approach could be used directly within std::enable_if_t<...>
. 可以在std::enable_if_t<...>
直接使用相同的方法。
Note : the approaches used above requires that the arguments are deduced as bool
, ie, they pretty much need to be of type bool
. 注意 :上面使用的方法要求将参数推导为bool
,即,它们非常需要为bool
类型。 Since the function shouldn't be callable with int
parameters and these would convert to bool
, testing whether the argument type is convertable to bool
doesn't seem appropriate. 由于该函数不应使用int
参数进行调用,而这些参数会转换为bool
,因此测试参数类型是否可转换为bool
似乎不合适。 However, it may be reasonable to allow some conversions. 但是,允许进行一些转换可能是合理的。 If so, a corresponding trait would be used in the first paramter to std::enable_if_t
. 如果是这样,则将在第一个参数std::enable_if_t
使用相应的特征。
Just use a static assert. 只需使用静态断言即可。 This works perfectly well: 这非常好用:
int bin_to_dec() {
return 0;
}
template<typename T, typename ... Args>
int bin_to_dec(T first, Args ... rest)
{
static_assert(std::is_same<bool, T>::value, "Only valid for bools");
return (first ? 1 : 0) + (bin_to_dec(rest...) << 1);
}
int main()
{
cout<<bin_to_dec(true, true, false, true)<<endl;
cout<<bin_to_dec(1, 2, 3)<<endl; //compile error
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.