试图搜索这个答案,我注意到问题的标题 关于可变参数模板函数在搜索时非常缺乏信息 所以。您只知道问题是关于可变参数模板。希望我的 之前没有问过问题,标题会帮助人们找到它。
所以,我想创建一个具有可变参数模板参数的函数。更多 确切地说,作为一个例子,假设我想要编译时的排列 数组。这是一个有效的代码:
template <typename... Ts> struct Sequence {};
template <typename T, unsigned Size, typename... SeqTis> struct Permute;
template <typename T, unsigned Size, typename... SeqTis>
struct Permute<T, Size, Sequence<SeqTis...> > {
using type = typename std::array<T, Size>;
constexpr static type permute(const type ar) {
return { (ar[SeqTis::value])... };
}
};
然后以下是完全合法的:
using T0 = std::integral_constant<int, 0>;
using T1 = std::integral_constant<int, 1>;
using T2 = std::integral_constant<int, 2>;
using Perm120 = Permute<int, 3, Sequence<T1, T2, T0> >;
using arr3 = Perm120::type;
constexpr arr3 ar {5,7,2};
constexpr arr3 arPerm = Perm120::permute(ar);
我现在正试图避免使用结构,所以我写了以下内容:
template <typename T, unsigned Size, typename... SeqTis>
constexpr typename std::array<T, Size>
permutefun<T, Size, Sequence<SeqTis...> >(const typename std::array<T, Size> ar) {
return { (ar[SeqTis::value])... };
}
GCC拒绝这样说
essai.cpp:19:11: error: expected initializer before ‘<’ token
permutefun<T, Size, Sequence<SeqTis...> >(const typename std::array<T, Size> ar) {
^
为什么会这样?
答案 0 :(得分:4)
你的语法看起来像尝试部分函数专门化,但这不是你想要的,所以这不是你应该写的。由于不支持部分函数特化,编译器会被意外的<
混淆。
template <typename T, unsigned Size, typename... SeqTis>
constexpr std::array<T, Size>
permutefun(const std::array<T, Size> ar) {
// ^ removed the <...>
return { (ar[SeqTis::value])... };
}
此外,您在此处不需要typename
,因为已知std::array<T, Size>
是一种类型。把它放进去很好,但没有它也能正常工作。
答案 1 :(得分:4)
要添加到以前的答案,您还需要有一个方便的语法来调用permutefun
,但是当前的模板参数
template <typename T, unsigned Size, typename... SeqTis>
不方便,因为你必须打电话
permutefun <int, 3, T1, T2, T0>(ar);
解决方案是通过两个步骤推导出论点:
#include <array>
template <typename... Ts> struct Sequence {};
template <typename... SeqTis, typename T, unsigned long Size>
constexpr std::array<T, Size>
permutefun(Sequence<SeqTis...>, const std::array<T, Size> ar) {
return { (ar[SeqTis::value])... };
}
template <typename Seq, typename T, unsigned long Size>
constexpr std::array<T, Size>
permutefun(const std::array<T, Size> ar) {
return permutefun(Seq(), ar);
}
int main ()
{
using T0 = std::integral_constant<int, 0>;
using T1 = std::integral_constant<int, 1>;
using T2 = std::integral_constant<int, 2>;
using Perm120 = Sequence<T1, T2, T0>;
using arr3 = std::array <int, 3>;
constexpr arr3 ar = {5,7,2};
constexpr arr3 arPerm = permutefun <Perm120>(ar);
}
现在参数T, Size
最后出现,因此由输入数组自动推断。参数Seq
首先出现,但要推断其“解压缩”参数SeqTis...
,您需要调用permutefun
的第二个重载。这允许方便的语法
permutefun <Perm120>(ar);
第二次重载本身可能很有用,因为它允许使用替代语法
Perm120 perm;
permutefun(perm, ar);
另请注意,std::array::operator[]
仅在C ++ 14中为constexpr
。例如,这不能用Clang 3.3和-std=c++11
进行编译。
答案 2 :(得分:1)
你的意思是:
template <typename T, unsigned Size, typename... SeqTis>
constexpr std::array<T, Size>
permutefun(const typename std::array<T, Size> ar) {
return { (ar[SeqTis::value])... };
}
部分模板专业化不适用于功能。