即使模板语法所隐含的语义不同,我也不知道为什么下面的代码块能够编译和运行。类A
接受模板类型Data
,并包含模板类型data
的成员Data
。它还具有一个构造函数,该构造函数按值接受Data
的实例,并使用假定的复制构造函数实例化成员data
。另一个类C
具有一个任意构造函数,该构造函数采用指向某个任意类B
的指针并将其存储为成员foo
。当Data
中的A
模板化为C
类型,并且A<C>
实例化了C
的构造函数接受的参数(即指向{{ 1}})可能会遇到编译器错误,因为尚未告知B
如何处理任意参数并将其传递给A
构造函数。仅被告知将Data
的副本构造函数与现有实例一起使用。但是,此代码使用clang和c ++ 11进行编译并显示true。我假设这是一个编译器错误,而不是功能,但也许我缺少有关C ++模板工作方式的信息?我也对此功能的正确语法感到好奇,(将任意模板参数传递给Data
的构造函数,并将它们转发给类型A
的构造函数)是我的实际意图。
Data
编辑:
正确的方法是parameter packing
#include <iostream>
template<typename Data>
struct A {
Data data;
A(Data data_) : data(data_) { }
};
struct B {
B() { }
};
struct C {
B* foo;
C(B* foo_) : foo(foo_) { }
};
int main() {
B foo;
A<C> thing = A<C>(&foo);
std::cout << (thing.data.foo == &foo) << std::endl;
return 0;
}
答案 0 :(得分:0)
编译代码的原因是因为struct C
的构造函数未标记为显式。实际上,A<C>
对象在其构造函数中需要一个C
对象。但是您提供了一个指向b的指针。由于没有将单个参数ctor标记为显式的,因此编译器选择从输入参数到所需参数的适当转换是合法的。
通常,静态代码分析器会将其标记为不受欢迎的,因为您永远不需要这种自动或意外的转换。因此,您确实应该使用显式关键字标记所有单个参数ctor。