C++ std::初始值设定项\u列表作为构造函数的模板参数

C++ std::初始值设定项\u列表作为构造函数的模板参数,c++,c++11,constructor,initializer-list,type-deduction,C++,C++11,Constructor,Initializer List,Type Deduction,考虑一个从std容器继承的类,该类使用一个模板构造函数调用容器的底层构造函数。此模板构造函数适用于简单的复制和移动构造函数,但不适用于初始值设定项\u list构造函数 模板 类测试:公共容器{ 公众: 使用容器类型=容器类型; test(){} //模板构造函数 模板 测试(T) :container_T(T){} //没有这个,它就无法编译 测试(标准::初始值设定项\u列表l) :container_T(l){} }; int main(){ 测试vdi1; 测试vdi2({1,2,3,4

考虑一个从std容器继承的类,该类使用一个模板构造函数调用容器的底层构造函数。此模板构造函数适用于简单的复制和移动构造函数,但不适用于初始值设定项\u list构造函数

模板
类测试:公共容器{
公众:
使用容器类型=容器类型;
test(){}
//模板构造函数
模板
测试(T)
:container_T(T){}
//没有这个,它就无法编译
测试(标准::初始值设定项\u列表l)
:container_T(l){}
};
int main(){
测试vdi1;
测试vdi2({1,2,3,4,5,6,7,8,9});
标准::cout
为什么初始值设定项列表不是由模板构造函数推导出来的

原因是
{1,2,3,4,5,6,7,8,9}
只是一个没有类型的同步构造。因此,编译器无法为此同步构造推断类型
t
,并且第一个构造函数失败

然而,根据特殊的标准规则,
std::initializer\u list
(除其他外)可以从这个同步构造中构造出来,
T
可以推断为
int
。因此,第二个构造器可以工作

通过与函数模板参数类型推断进行对比

auto x = {1,2,3,4,5,6,7,8,9};
编译器将x的类型设置为
std::initializer_list
。也有特殊的标准规则规定必须如此。严格来说,这不是类型推断,因为如上所述,
{1,2,3,4,5,6,7,8,9}
没有要推断的类型。(这里发生的唯一类型推断是
std::initializer_list
中的
T=int
),编译器选择(它不推断)
x
的类型为
std::initializer\u list
。在任何情况下,使用滥用语言说
x
的类型被推断为
std::initializer\u list
,都没有害处

最后,正如DyP在评论中所说,您可能希望从基本容器类继承所有构造函数(而不仅仅是那些接受一个参数的构造函数)。您可以通过删除当前拥有的所有构造函数并将这一行添加到
test

using container_type::container_type;

实际上,它不是复制或移动,它们是隐式声明的,除了您的ctor之外。它不适用于
初始值设定项\u列表
s,因为它们无法/无法推导。为什么不使用继承ctor?
使用container\u t::container\u t;
@DyP为什么它应该复制或移动ctor?编辑注释(…还是少了一个词:实际上,它不是复制或移动的。我的意思是:一个复制或移动的模板从来都不是复制或移动的复制或移动的。看起来你想阅读