我看到blog post使用了非类型的可变参数模板(gcc目前不支持,只有clang支持)。
template <class T, size_t... Dimensions>
struct MultiDimArray { /* ... */ };
帖子中的示例编译得很好但我没能使用函数模板。
任何人都可以帮助找出正确的语法(如果存在)吗?
int max(int n) { return n; } // end condition
template <int... N> // replacing int... with typename... works
int max(int n, N... rest) // !! error: unknown type name 'N'
{
int tmp = max(rest...);
return n < tmp? tmp : n;
}
#include <iostream>
int main()
{
std::cout << max(3, 1, 4, 2, 5, 0) << std::endl;
}
答案 0 :(得分:12)
您只是混淆了类型名称和非类型名称。你想要的东西根本行不通。
你可能可能在函数中使用可变参数非类型模板,但不能作为(非模板)参数:
template <int N, int... Rest>
int max()
{
int tmp = max<Rest...>();
return N < tmp ? tmp : N;
}
std::cout << max<3, 1, 4, 2, 5, 0>() << std::endl;
...虽然我没有对此进行测试,但我不确定 这应该如何工作,因为您需要将部分专业化作为基本案例。您可以通过调度到部分专用的结构来解决这个问题:
template <int N, int... Rest>
struct max_t {
static int const value = max_t<Rest...>::value > N ? max_t<Rest...>::value : N;
};
template <int N>
struct max_t<N> {
static int const value = N;
};
template <int... NS>
int max()
{
return max_t<NS...>::value;
}
这样可行。
答案 1 :(得分:10)
这将打印出所有元素, get max可以类似地实现
template <int N>
void foo(){
cout << N << endl;
}
template <int N, int M, int ... Rest>
void foo(){
cout << N << endl;
foo<M, Rest...>();
}
int main(){
foo<1, 5, 7>();
return 0;
}
答案 2 :(得分:7)
以下是定义仅接受int
参数的可变参数函数模板的两种方法。第一个在实例化时生成硬错误,第二个使用SFINAE:
template<typename... T>
struct and_: std::true_type {};
template<typename First, typename... Rest>
struct and_
: std::integral_constant<
bool
, First::value && and_<Rest...>::value
> {};
template<typename... T>
void
foo(T... t)
{
static_assert(
and_<std::is_same<T, int>...>::value
, "Invalid parameter was passed" );
// ...
}
template<
typename... T
, typename = typename std::enable_if<
and_<std::is_same<T, int>...>::value
>::type
>
void
foo(T... t)
{
// ...
}
如您所见,此处未使用非类型模板参数。
答案 3 :(得分:1)
以下是您在max
示例中如何实现可变参数的方法,以便它可以使用任意数量的算术参数:
template<typename T, typename ... Ts>
struct are_arithmetic{
enum {
value = std::is_arithmetic<T>::value && are_arithmetic<Ts...>::value
};
};
template<typename T>
struct are_arithmetic<T>{
enum {
value = std::is_arithmetic<T>::value
};
};
template<typename Arg, typename = typename std::enable_if<std::is_arithmetic<Arg>::value>::type>
Arg max(Arg arg){
return arg;
}
template<typename Arg, typename Arg1, typename ... Args, typename = typename std::enable_if<are_arithmetic<Arg, Arg1, Args...>::value>::type>
auto max(Arg arg, Arg1 arg1, Args ... args){
auto max_rest = max(arg1, args...);
return arg > max_rest ? arg : max_rest;
}
int main(){
auto res = max(1.0, 2, 3.0f, 5, 7l);
}
这很好,因为它可以采用任何数字类型,并且会返回原始类型的最大数量,而不仅仅是int
。