如果std :: make_unique从未被调用,为什么默认成员初始化中不需要该参数?

iFreilicht

无论成员是否使用过,默认成员初始化都需要引用现有的构造函数。因此,看一个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是正确的。可能是编译器错误吗?

用户名

这是一个独立的示例,演示了该问题:

template <typename T>
int f() {
  return T();
}

struct S {
  int i = f<void>();
  S() : i(0) { }
};

在您的示例中,f名为make_unique,它不会返回int,但是从根本上不会改变任何内容。

是的,Visual Studio的编译器接受,其他编译器则不接受。Visual Studio延迟实例化它不需要的模板。其他编译器f<void>在发现引用后立即实例化

从C ++ 11引用:

14.7.1隐式实例化[temp.inst]

9如果以涉及过载解析的方式使用函数模板或成员函数模板特化,则隐式实例化特化的声明(14.8.3)。

这支持发出错误的编译器:f<void>()需要重载解析,因此将实例化f<void>类模板实例化还有一些余地:

14.7.1隐式实例化[temp.inst]

6如果重载解析过程可以在不实例化类模板定义的情况下确定要调用的正确函数,则不确定该实例是否实际发生。

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

除非功能模板存在类似的例外,并且我无法找到一个例外,否则我认为需要编译器来诊断错误,并且功能模板目前实际上不支持惰性实例化。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么 std::make_unique 调用复制构造函数

来自分类Dev

如果std :: shared_ptr是由非null构造的,为什么它不需要知道完整类型呢?

来自分类Dev

std :: enable_if如果参数是函数?

来自分类Dev

如果KEY是std :: list或std :: vector而不是值,则std :: map的默认行为是什么?

来自分类Dev

如果std :: function捕获了unique_ptr,该如何复制?

来自分类Dev

当包含std :: promise作为成员时,为什么结构的make_unique失败?

来自分类Dev

为什么C ++字符串不需要std :: forward来调用所需的函数?

来自分类Dev

为什么调用`lower_bound`函数不需要`std`前缀?

来自分类Dev

如果全局定义std :: ifstream为什么不更新

来自分类Dev

为什么std模板功能不需要限定?

来自分类Dev

如果向量为空,std :: vector :: data()应该返回什么?

来自分类Dev

如果找不到元素,std :: find会返回什么

来自分类Dev

如何检查std :: unique_ptr是否为空(如果它位于std :: vector中)?

来自分类Dev

如果需要将数组清零,用一对大括号初始化std :: array是否正确?

来自分类Dev

什么时候不需要“如果”?

来自分类Dev

'make_unique'不是'std'的成员

来自分类Dev

这是线程安全的向量吗?如果是,为什么为什么std :: vector的某些方法需要锁定才能保证线程安全,而其他方法则不需要?

来自分类Dev

如果在std :: wstring声明和std :: setlocale()之后调用mbrlen(),则无法返回

来自分类Dev

如果A有析构函数,std :: unique_ptr <A>什么时候需要特殊的删除器?

来自分类Dev

为什么std :: atomic的默认构造函数不默认初始化底层存储值?

来自分类Dev

是否可以在默认成员初始化程序中调用非静态成员函数?

来自分类Dev

作为类成员的std :: array <int,N>中的元素是否默认初始化

来自分类Dev

为什么不能将类内初始化的const const std :: string`设为静态成员

来自分类Dev

为什么默认成员值禁止使用括号列表初始化?

来自分类Dev

如果成员是模板类,则在初始化列表中初始化某个类的成员

来自分类Dev

为什么赋值初始化如果不使用它就需要复制构造函数

来自分类Dev

如果构造函数无法返回null,为什么初始化后需要进行类型检查?

来自分类Dev

如果构造不需要括号,该怎么办?

来自分类Dev

我是否需要在构造函数中显式初始化std :: unique_ptr?

Related 相关文章

  1. 1

    为什么 std::make_unique 调用复制构造函数

  2. 2

    如果std :: shared_ptr是由非null构造的,为什么它不需要知道完整类型呢?

  3. 3

    std :: enable_if如果参数是函数?

  4. 4

    如果KEY是std :: list或std :: vector而不是值,则std :: map的默认行为是什么?

  5. 5

    如果std :: function捕获了unique_ptr,该如何复制?

  6. 6

    当包含std :: promise作为成员时,为什么结构的make_unique失败?

  7. 7

    为什么C ++字符串不需要std :: forward来调用所需的函数?

  8. 8

    为什么调用`lower_bound`函数不需要`std`前缀?

  9. 9

    如果全局定义std :: ifstream为什么不更新

  10. 10

    为什么std模板功能不需要限定?

  11. 11

    如果向量为空,std :: vector :: data()应该返回什么?

  12. 12

    如果找不到元素,std :: find会返回什么

  13. 13

    如何检查std :: unique_ptr是否为空(如果它位于std :: vector中)?

  14. 14

    如果需要将数组清零,用一对大括号初始化std :: array是否正确?

  15. 15

    什么时候不需要“如果”?

  16. 16

    'make_unique'不是'std'的成员

  17. 17

    这是线程安全的向量吗?如果是,为什么为什么std :: vector的某些方法需要锁定才能保证线程安全,而其他方法则不需要?

  18. 18

    如果在std :: wstring声明和std :: setlocale()之后调用mbrlen(),则无法返回

  19. 19

    如果A有析构函数,std :: unique_ptr <A>什么时候需要特殊的删除器?

  20. 20

    为什么std :: atomic的默认构造函数不默认初始化底层存储值?

  21. 21

    是否可以在默认成员初始化程序中调用非静态成员函数?

  22. 22

    作为类成员的std :: array <int,N>中的元素是否默认初始化

  23. 23

    为什么不能将类内初始化的const const std :: string`设为静态成员

  24. 24

    为什么默认成员值禁止使用括号列表初始化?

  25. 25

    如果成员是模板类,则在初始化列表中初始化某个类的成员

  26. 26

    为什么赋值初始化如果不使用它就需要复制构造函数

  27. 27

    如果构造函数无法返回null,为什么初始化后需要进行类型检查?

  28. 28

    如果构造不需要括号,该怎么办?

  29. 29

    我是否需要在构造函数中显式初始化std :: unique_ptr?

热门标签

归档