Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 变量构造函数是否应该隐藏隐式生成的构造函数?_C++_Templates_C++11_Copy Constructor_Variadic Templates - Fatal编程技术网

C++ 变量构造函数是否应该隐藏隐式生成的构造函数?

C++ 变量构造函数是否应该隐藏隐式生成的构造函数?,c++,templates,c++11,copy-constructor,variadic-templates,C++,Templates,C++11,Copy Constructor,Variadic Templates,变量构造函数是否应该隐藏隐式生成的构造函数,即默认构造函数和复制构造函数 struct Foo { template<typename... Args> Foo(Args&&... x) { std::cout << "inside the variadic constructor\n"; } }; int main() { Foo a; Foo b(a); } 同样,这两行都被打印。隐式声明的复

变量构造函数是否应该隐藏隐式生成的构造函数,即默认构造函数和复制构造函数

struct Foo
{
    template<typename... Args> Foo(Args&&... x)
    {
        std::cout << "inside the variadic constructor\n";
    }
};

int main()
{
    Foo a;
    Foo b(a);
}

同样,这两行都被打印。

隐式声明的复制构造函数的声明实际上没有被抑制。由于重载解析的规则,它没有被调用

隐式声明的复制构造函数的形式为
Foo(constfoo&)
。其中重要的一点是它采用常量引用。构造函数模板采用非常量引用

a
不是常量,因此非常量用户声明的构造函数模板优于隐式声明的副本构造函数。要调用隐式声明的复制构造函数,可以使
a
const:

const Foo a;
Foo b(a);
或者您可以使用
static\u cast
获取对
a
的常量引用:

Foo a;
Foo b(static_cast<const Foo&>(a));
fooa;
Foo b(静态演员阵容(a));
描述这一点的重载解析规则主要在C++0x FCD的§13.3.3.2/3中找到。这个特定的场景,结合了左值和右值引用,在第303页的各种示例中进行了描述


可变构造函数模板将禁止隐式声明的默认构造函数,因为可变构造函数模板是用户声明的,并且只有在没有用户声明的构造函数时才提供隐式声明的默认构造函数(C++0x FCD§12.1/5):

如果类
X
没有用户声明的构造函数,则没有参数的构造函数将隐式声明为默认构造函数

可变构造函数模板不会抑制隐式声明的复制构造函数,因为只有非模板构造函数可以是复制构造函数(C++0x FCD§12.8/2、3和8):

如果类
X
的非模板构造函数的第一个参数类型为
X&
const X&
volatile X&
const volatile X&
,并且没有其他参数或所有其他参数都具有默认参数,则该类的非模板构造函数为复制构造函数

X
的非模板构造函数是移动构造函数,如果其第一个参数的类型为
X&&
const X&&
volatile X&&
const volatile X&
,或者没有其他参数,或者所有其他参数都有默认参数

如果类定义没有显式声明复制构造函数,并且没有用户声明的移动构造函数,则复制构造函数将隐式声明为默认值


我刚刚在gcc45上运行了一个快速测试,一个常规的、非可变的模板构造函数也可以防止创建编译器生成的默认构造函数。我怀疑C++0x中的规则发生了变化。@Dennis:如果C++0x会改变C++0x中引入的规则,我会非常惊讶<代码>:)@Dennis那么链接的答案是假的吗?它说“模板构造函数或赋值运算符不会抑制编译器生成的模板构造函数或赋值运算符”。@sbi:我想说的是,即使没有C++0x特性,gcc45也不会按照他认为的方式工作。所以要么是C++0x中的规则改变了,gcc在本例中是非标准的,要么是其他人错了。假设规则改变了,两个人就对了,那么这就是应该采取的民主立场;)老实说,我不知道。模板通常会把我弄糊涂。@James“模板构造函数[…]从来都不是复制构造函数”->所以g++4.5.0有缺陷,第二行不应该打印任何内容?你说的FCD是指n3090吗?@Fred:FCD是n3092;我必须更新报价,因为我有n3035开放的某些原因,有一些变化n3092。。。很抱歉。@James这也发生在非变量模板上,我已经更新了我的问题@弗雷德:看更新;您看到的行为是由于重载解析规则造成的(因此,这不是g++中的错误)。@FredOverflow,GCC的行为符合C++03的规则(根据合理的解释,但标准并不明确)。C++0x已明确规定了规则,GCC将不得不更改其行为(如@James所说,只有n3092明确规定了规则-之前的所有草案也不明确)。
Foo a;
Foo b(static_cast<const Foo&>(a));