【问题标题】:What is the meaning of ellipses in a copy constructor?复制构造函数中省略号的含义是什么?
【发布时间】:2015-12-29 21:27:56
【问题描述】:

考虑以下程序:

#include <iostream>
struct Test
{
    int a;
    Test() : a(3)
    { }
    Test(const Test& t...)
    {
        std::cout<<"Copy constructor called\n";
        a=t.a;
    }
    int get_a()
    {
        return a;
    }
    ~Test()
    {
        std::cout<<"Destructor is called\n";
    }
};
int main()
{
    Test t;
    Test* t1=new Test(t);
    std::cout<<t.get_a()<<'\n';
    std::cout<<t1->get_a()<<'\n';
    delete t1;
}

仔细观察复制构造函数参数中的三个点 当我尝试这个程序时,我真的很惊讶。它有什么用?什么意思?

语言规范对此有何评论?

我知道三个点用来表示可变参数函数中的可变长度参数 像printf()scanf() 等以及C99 引入的可变参数宏。在 C++ 中,如果我没记错的话,它们是在可变参数模板中使用的。
这段代码格式正确吗?这个可变参数复制构造函数可以接受任意数量的参数吗?

它在 g++ 4.8.1 和 MSVS 2010 上编译和运行良好。

【问题讨论】:

  • Test(const Test&amp; t, ...)(注意逗号)
  • 任何可以使用类型本身的一个值调用并通过引用获取它的构造函数都是可能的复制构造函数。可以提供可选的进一步参数这一事实并不重要。
  • @PiotrSkotnicki:那么,为什么不需要逗号?
  • @PravasiMeet 我认为语言规范明确允许这样做。我不确定为什么他们明确允许这样做,但他们确实允许。
  • 我更新了我的答案,解释了什么是抽象声明符。

标签: c++ copy-constructor variadic-functions


【解决方案1】:

8.3.5 部分中的标准草案 [dcl.fct], ...... 的同义词,除非 ... 是抽象声明符的一部分(强调我的):

[...]如果参数声明子句以省略号结尾 或函数参数包(14.5.3),参数的数量应 等于或大于没有的参数个数 默认参数,不是函数参数包。 在哪里 语法正确且其中“...”不是 抽象声明符,“, ...”与“...”同义。[...]

所以它是一个variadic function,据我所知,没有其他参数,这也是一个有效的复制构造函数,来自12.8 部分[class.copy]

类 X 的非模板构造函数是一个复制构造函数,如果它 第一个参数的类型为 X&、const X&、volatile X& 或 const volatile X&,或者没有其他参数,或者所有其他 参数具有默认参数 (8.3.6)。

这个注释说省略号不是参数:

void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow
                      // a parameter with a default argument

上面的规范文本支持:

如果参数声明子句以省略号[...]结束

注意,因为它被要求 abstract-declarator 是没有标识符的声明符。

【讨论】:

【解决方案2】:

它有什么用?什么意思?

是的,它引入了可变参数函数。

在 C++ 中,如果我没记错的话,它们会在可变参数模板中使用。

语法和语义不同。这是一个“C 风格”的可变参数函数,而不是可变参数 template 函数。此外,复制构造函数不能是模板函数。

类 X 的 非模板 构造函数是 复制构造函数,如果它 第一个参数的类型为 X&、const X&、volatile X& 或 const volatile X&,或者 没有其他参数 或者所有其他 参数具有默认参数 (8.3.6)。

根据最终草案中的 §12.8.2(强调我的)

这段代码格式正确吗?这个可变参数复制构造函数可以接受任意数量的参数吗?

如果省略号包含参数,则不再是复制构造函数,而是简单构造函数。如果没有,那么它是一个有效的复制构造函数。

 X(const X&, int = 1, double = 5); // copy-ctor
 X(const X&, int = 1, double); // constructor

【讨论】:

  • 所以我可以说这个链接中的程序没有复制构造函数,因为它没有使用默认参数。 ideone.com/VuNTU5
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 2011-03-31
  • 2015-08-08
  • 2020-03-27
  • 2018-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多