C ++ 11:可变参数模板推导逻辑

费伦茨·迪克(Ferenc Deak)

我有以下构造:

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>吗?(从标准的几行中可以做:))

https://ideone.com/o6u0D6

Angew不再为SO感到骄傲

void是和其他类型一样的类型(准确地说是不完整的类型)。这意味着它可以正常用作类型模板参数的模板参数。以您的类模板为例,这些都是完全有效且独特的实例化:

some_class<void>
some_class<void, void>
some_class<void, void, void>
some_class<void, char, void>

在第一种情况下,参数包Args具有一个元素:void在第二种情况下,它具有两个元素:voidvoid等等。

这与情况完全不同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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章