当前位置: 首页 > 知识库问答 >
问题:

具有显式默认构造函数的类型的复制初始化上下文中{}的隐式转换序列

卢志行
2023-03-14
struct nullopt_t { explicit nullopt_t() = default; };

被关闭为非缺陷(NAD),其基本原理如下

2021-06-14反射器轮询:

当前的措辞阻止了来自{}的隐式转换序列。

struct my_nullopt_t {
    explicit constexpr my_nullopt_t() = default;
};

struct S {
    constexpr S() {} // user-provided: S is not an aggregate
    constexpr S(S const&)      = default;
    S& operator=(S const&)     = default; // #1
    S& operator=(my_nullopt_t) = delete;  // #2
};

int main() {
    S s{};
    s = {};  // #3
}

但是考虑到上面反射者的评论,我可能错了。可能是[over.match.list]/1

在复制列表初始化中,如果选择显式构造函数,则初始化格式不正确。[注意:这与其他情况([over.match.ctor],[over.match.copy])不同,在其他情况下,复制初始化只考虑转换构造函数。只有当初始化是重载解析最终结果的一部分时,此限制才适用。-结束注意]

通过[over.ics.list]/7中的条目来管理这个案例?

  • 有哪些标准段落支持上述反射器的基本原理,例如应用于上述例子?
    • 这是否支持GCC拒绝上面的程序,因此Clang接受它是错误的?

共有1个答案

鲜于雨石
2023-03-14

GCC是对的,Clang和MSVC是错的。这一点在:

  • CWG1228:复制列表初始化和显式构造函数

它也作为NAD关闭。

    null
struct MyList {
  explicit MyStore(int initialCapacity);
};

struct MyInt {
  MyInt(int i);
};

struct Printer {
  void operator()(MyStore const& s);
  void operator()(MyInt const& i);
};

void f() {
  Printer p;
  p({23});
}
 类似资料:
  • 上面引号中加粗的表示对复制构造函数的调用是显式的,对吗?是G++错了还是我对标准的解释错了?

  • 显式复制构造函数不允许类似于的东西,并将复制使用强制为。此外,显式复制构造函数也不允许从函数中按值返回对象。然而,我尝试用大括号替换复制初始化,就像这样 我得到的错误(g 5.2) 错误:没有匹配的函数用于调用'Foo::Foo(Foo 或(叮当声) 错误:结构初始值设定项中的元素过多 删除使代码在g下可编译,但clang仍然会失败,并出现相同的错误(感谢@stophen)。这是怎么回事?统一初始

  • 问题内容: 以下是两种方法: 具有所有类属性的构造函数 优点:我必须输入确切数量的参数类型,所以如果出现错误,编译器会警告我(顺便说一句,有什么方法可以防止错误地在参数列表中切换两个Integer的问题?) 缺点:如果我有很多属性,则实例化行可能会变得很长,并且可能跨越两行或更多行 setter和默认的空构造函数 优点:我可以清楚地看到自己的设置,因此,如果我做错了什么,我可以在键入时立即查明它(

  • 问题内容: 警告#1:实际上这是一个潜在的两部分:首先,私有内部类的构造函数是否具有形式参数?如果是,为什么JLS拒绝呢?如果没有,怎么/为什么不呢? 注意事项2: 此问题不用于推测。 我仅在寻找 权威 答案。 默认构造函数在JLS 8.8.9 中定义,该声明(部分说明): 除了在 非私有 内部成员类中之外,默认构造函数没有形式参数,在默认情况下,默认构造函数隐式声明一个表示该类的立即封闭实例的形

  • CLANG6、CLANG7和gcc 7.1、7.2和7.3都同意以下代码是有效的C++17代码,但在C++14和C++11下有歧义。MSVC2015和2017也接受它。然而,即使在C++17模式下,GCC-8.1和8.2也拒绝了它: 接受它的编译器选择模板化的显式转换函数。 拒绝它的编译器同意在以下两个方面存在歧义: null 以下是来自(接受代码)的错误:

  • 隐式默认构造函数有一个空主体和一个空初始值设定项列表(未定义的原始类型,默认构造函数用于用户定义的类型)。 这篇帖子说 确实进行了成员级值初始化,但在进行初始化时调用默认构造函数有什么意义 ? 是否调用隐式默认构造函数,以确保调用用户定义类型(可能具有非平凡的默认构造函数)的默认构造函数? 使现代化 似乎在调用编译器生成的隐式默认构造函数后,对象可能无法一致实例化,即未定义基元类型,并且用户定义的