我正在尝试使用可变参数模板并遇到一个奇怪的问题,我不明白为什么会出现错误消息。
template<int v0, int ...Vs>
class Foo
{
public:
template<typename nested = void,
typename = void>
class Reduce
{
public:
static int const value = v0;
};
template<typename nested>
class Reduce<nested,
typename std::enable_if<0<sizeof...(Vs)>::type>
{
public:
static int const value = v0 + Foo<Vs...>::template Reduce<>::value;
};
};
此代码带来错误消息
//example code
int s = Foo<0,1,2,3,4,5>::Reduce<>::value;
std::cout << s << std::endl;
error: incomplete type 'F<5>::Reduce<>' used in nested name specifier
我插入了嵌套的虚拟模板参数,因为模板类中的嵌套模板类不能完全专门化。实际上我不明白为什么编译器会抱怨类型不完整 当我将可变参数更改为
时template<int v0, int ...Vs>
class Reduced
{
public:
static int const value = v0 + Reduce<Vs...>::value;
};
template<int v0>
class Reduced<v0>
{
public:
static int const value = v0;
};
template<int v0, int ...Vs>
class Foo
{
public:
class Reduce
{
public:
static int const value = Reduced<v0, Vs...>::value;
};
};
它有效,但我不知道为什么另一个没有。知道为什么编译器会抛出那个错误吗?谢谢你的帮助。
答案 0 :(得分:1)
typename std::enable_if<0<sizeof...(Vs)>::type
你需要将不平等检查包括在parens中。
typename std::enable_if< (0 < sizeof...(Vs)) >::type
答案 1 :(得分:1)
这归功于C ++标准的引用§14.7.3/ p16显式特化[temp.expl.spec] (强调我的):
在类的成员的显式专门化声明中 模板或出现在命名空间范围内的成员模板 成员模板及其一些封闭的类模板可能会保留 unspecialized,,但声明不得明确 如果它包含类模板,则专门化一个类成员模板 也没有明确的专业。
也就是说,你不能拥有专门类型Foo<int...>::Reduced<>
的对象,除非Foo
封闭类也是专门的。
您可以通过以下方式修改此内容:
template<int v0, int ...Vs>
class Foo {
public:
class Reduce {
public:
static int const value = v0 + Foo<Vs...>::Reduce::value;
};
};
template<int v0>
class Foo<v0> {
public:
class Reduce {
public:
static int const value = v0;
};
};
或者你可以摆脱嵌套类:
template<int v0, int ...Vs>
class Foo {
public:
static int const value = v0 + Foo<Vs...>::value;
};
template<int v0>
class Foo<v0> {
public:
static int const value = v0;
};
C ++ 17引入了折叠表达式。使用folds表达式,您只需执行以下操作即可执行以下操作:
template<int v0, int ...Vs>
class Foo {
public:
static const int s = v0 + (Vs + ...);
};