我有以下构造:
template <class... Args>
class some_class
{
public:
some_class() = default;
some_class(Args...) = delete;
~some_class() = default;
};
template<>
class some_class<void>
{
public:
some_class() = default;
~some_class() = default;
};
这样做的原因是,我只想允许用户使用默认构造函数创建对象,因此:
some_class<int,float> b;
应该工作,但是
some_class<int,float> c(1,3.4);
应该给我一个编译错误。
在某些时候,我还需要基于以下方面void
的专业化来创建模板void
:
some_class<void> a;
但是我误输入了:
some_class<> d;
突然我的代码停止编译,这给了我错误:
some_class<Args>::some_class(Args ...) [with Args = {}]’ cannot be
overloaded
some_class(Args...) = delete;
所以这里出现一个问题:我认为some_class<>
应该推论到void
专业化是错误的……我只是不知道为什么。可以请人解释为什么some_class<>
(即:空参数列表)与some_class<void>
吗?(从标准的几行中可以做:))
void
是和其他类型一样的类型(准确地说是不完整的类型)。这意味着它可以正常用作类型模板参数的模板参数。以您的类模板为例,这些都是完全有效且独特的实例化:
some_class<void>
some_class<void, void>
some_class<void, void, void>
some_class<void, char, void>
在第一种情况下,参数包Args
具有一个元素:void
。在第二种情况下,它具有两个元素:void
和void
。等等。
这与情况完全不同some_class<>
,在这种情况下,参数包具有零个元素。您可以使用sizeof...
以下方法轻松演示这一点:
template <class... Pack>
struct Sizer
{
static constexpr size_t size = sizeof...(Pack);
};
int main()
{
std::cout << Sizer<>::size << ' ' << Sizer<void>::size << ' ' << Sizer<void, void>::size << std::endl;
}
这将输出:
0 1 2
我真的想不出要引用的标准的相关部分。可能是这样的(C ++ 11 [temp.variadic] 14.5.3 / 1):
一个模板参数包是接受零个或多个模板参数模板参数。[示例:
template<class ... Types> struct Tuple { }; Tuple<> t0; // Types contains no arguments Tuple<int> t1; // Types contains one argument: int Tuple<int, float> t2; // Types contains two arguments: int and float Tuple<0> error; // error: 0 is not a type
—结束示例]
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句