[英]std::initializer_list as template argument for constructor
Consider a class which inherits from a std container with a template constructor which calls the underlying constructor of the container. 考虑一个继承自std容器的类,该类具有调用容器的底层构造函数的模板构造函数。 This template constructor works for the simple copy and move constructor but not for the initializer_list ctor.
此模板构造函数适用于简单复制和移动构造函数,但不适用于initializer_list ctor。
template<typename container_T>
class test : public container_T {
public:
using container_type = container_T;
test() {}
// templated constructor
template<typename T>
test(T t)
: container_T(t) {}
// without this it won't compile
test(std::initializer_list<typename container_T::value_type> l)
: container_T(l) {}
};
int main() {
test<std::deque<int>> vdi1;
test<std::deque<int>> vdi2({1,2,3,4,5,6,7,8,9});
std::cout << "vdi2 before:" << std::endl;
for(auto it : vdi2)
std::cout << it << std::endl;
test<std::deque<int>> vdi3(std::move(vdi2));
std::cout << "vdi2 before:" << std::endl;
for(auto it : vdi2)
std::cout << it << std::endl;
std::cout << "vdi3 before:" << std::endl;
for(auto it : vdi3)
std::cout << it << std::endl;
return 0;
}
If I remove the initializer_list
constructor vdi2
won't compile. 如果我删除了
initializer_list
构造函数, vdi2
将无法编译。 So my question: Why is the initializer_list not deduced by the template constructor? 所以我的问题:为什么初始化列表不是由模板构造函数推导出来的? And is it possible to do so?
这样可能吗?
why is the initializer_list not deduced by the templated constructor?
为什么initializer_list不是由模板化的构造函数推导出来的?
The reason is that {1,2,3,4,5,6,7,8,9}
is just a synctatic construct that doesn't have a type. 原因是
{1,2,3,4,5,6,7,8,9}
只是一个没有类型的同构构造。 Therefore, the compiler cannot deduce a type T
for this synctatic construct and the first constructor fails. 因此,编译器无法为此synctatic构造推导出类型
T
,并且第一个构造函数失败。
However, by special Standard rules std::initializer_list<T>
(among other things) can be construct from this synctatic construct and T
can be deduced to int
. 但是,通过特殊的标准规则,
std::initializer_list<T>
(以及其他内容)可以从此synctatic构造中构造,并且T
可以推导为int
。 Hence the second constructor works. 因此第二个构造函数工作。
By constrast with function template argument type deduction, with 通过与函数模板参数类型推导的约束,用
auto x = {1,2,3,4,5,6,7,8,9};
the compiler sets the type of x to be std::initializer_list<int>
. 编译器将x的类型设置为
std::initializer_list<int>
。 There are also special Standard rules that says it must be so. 还有一些特殊的标准规则,它必须如此。 Strictly speaking this is not type deduction because, as said above,
{1,2,3,4,5,6,7,8,9}
doesn't have a type to be deduced. 严格地说,这不是类型推断,因为如上所述,
{1,2,3,4,5,6,7,8,9}
没有要推断的类型。 (The only type deduction happening here is T = int
in std::initializer_list<T>
.) Here the compiler chooses (it doesn't deduce) the type of x
to be std::initializer_list<int>
. (此处发生的唯一类型推导是
std::initializer_list<T>
T = int
。)这里编译器选择(不推断) x
的类型为std::initializer_list<int>
。 In any case, there's no harm to use the abuse of language of saying that the type of x
is deduced to std::initializer_list<int>
. 在任何情况下,使用滥用语言说
x
的类型推导到std::initializer_list<int>
没有任何害处。
Finally, as DyP said in the comments, what you probably want is inheriting all constructors (not only those taking one argument) from the base container class. 最后,正如DyP在评论中所说,你可能想要的是从基础容器类继承所有构造函数(不仅仅是那些带有一个参数的构造函数)。 You can do this by removing all the constructors that you currently have and add just this line to
test
: 您可以通过删除当前拥有的所有构造函数来执行此操作,并添加此行以进行
test
:
using container_type::container_type;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.