默认成员初始化需要引用现有的构造函数,无论是否使用它。因此,查看一个没有默认构造函数的结构Foo:
struct Foo{
Foo(int x) : x_(x){}
int x_;
};很明显,以下内容无法工作,并导致编译错误:
class Bar0{
Foo foo = Foo(); #constructor Foo() doesn't exist
Bar0() : foo(0){}
}但是,std::unique_ptr和std::make_unique的情况就不同了
class Bar1{
unique_ptr<Foo> foo = make_unique<Foo>(); #compiler doesn't complain
Bar1() : foo(make_unique<Foo>(0)){}
}这是令人费解的,因为当Bar1包含一个foo不在初始化列表中的构造函数时,编译就会失败。
我可以证实这一点对MSVC12是正确的。会不会是编译器的错误?
发布于 2014-09-21 15:06:09
下面是一个自我包含的示例,演示了这个问题:
template <typename T>
int f() {
return T();
}
struct S {
int i = f<void>();
S() : i(0) { }
};在您的示例中,f名为make_unique,它不返回int,但这并没有从根本上改变任何事情。
是的,Visual的编译器接受这一点,而其他编译器则不接受。Visual延迟实例化它还不需要的模板。其他编译器一发现引用就会实例化f<void>。
引用C++11的话:
14.7.1隐式实例化temp.inst 9.如果函数模板或成员函数模板专门化的使用方式涉及重载解析,则将隐式实例化专门化声明(14.8.3)。
这支持发出错误的编译器:f<void>()需要重载解析,因此实例化了f<void>。类模板实例化有一些余地:
14.7.1隐式实例化temp.inst 6.如果重载解析过程可以在不实例化类模板定义的情况下确定要调用的正确函数,则未指定该实例化是否实际发生。
但是(与我最初在回答中所写的相反),我认为它不适用于整个功能体。
除非函数模板有类似的异常,而且我还没有找到异常,否则我认为需要编译器来诊断错误,而函数模板目前实际上不允许延迟实例化。
https://stackoverflow.com/questions/25959633
复制相似问题