首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么std::make_unique在默认成员初始化中不需要参数(如果它从未被调用)?

为什么std::make_unique在默认成员初始化中不需要参数(如果它从未被调用)?
EN

Stack Overflow用户
提问于 2014-09-21 13:21:04
回答 1查看 2.8K关注 0票数 0

默认成员初始化需要引用现有的构造函数,无论是否使用它。因此,查看一个没有默认构造函数的结构Foo

代码语言:javascript
复制
struct Foo{
    Foo(int x) : x_(x){}
    int x_;
};

很明显,以下内容无法工作,并导致编译错误:

代码语言:javascript
复制
class Bar0{
    Foo foo = Foo(); #constructor Foo() doesn't exist
    Bar0() : foo(0){}
}

但是,std::unique_ptrstd::make_unique的情况就不同了

代码语言:javascript
复制
class Bar1{
    unique_ptr<Foo> foo = make_unique<Foo>(); #compiler doesn't complain
    Bar1() : foo(make_unique<Foo>(0)){}
}

这是令人费解的,因为当Bar1包含一个foo不在初始化列表中的构造函数时,编译就会失败。

我可以证实这一点对MSVC12是正确的。会不会是编译器的错误?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-21 15:06:09

下面是一个自我包含的示例,演示了这个问题:

代码语言:javascript
复制
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.如果重载解析过程可以在不实例化类模板定义的情况下确定要调用的正确函数,则未指定该实例化是否实际发生。

但是(与我最初在回答中所写的相反),我认为它不适用于整个功能体。

除非函数模板有类似的异常,而且我还没有找到异常,否则我认为需要编译器来诊断错误,而函数模板目前实际上不允许延迟实例化。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25959633

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档