问题标签 [explicit-constructor]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
1910 浏览

c++ - C++17 中的显式默认构造函数

在 C++17 中,标准库中的空标记类型现在具有标记为 的默认构造函数explicit,并且也是= default. 例如,std::piecewise_construct_t现在定义为

我的问题很简单,从 C++14 发生这种变化的原因是什么?显式默认的显式默认构造函数(!)对于空类意味着什么?

(为了避免被标记为骗子:这个问题从 2010 年开始询问显式默认构造函数的目的,但那是 C++11 之前和很久以前的事了,所以事情可能已经改变了。这个问题是最近的,但是答案似乎表明,无论是否存在默认构造函数,都会执行聚合初始化,所以我很好奇最新标准中这种变化的原因。)

0 投票
1 回答
105 浏览

c++ - c++ 在隐式情况下调用显式构造函数

我使用 g++ 6.3.0 编译了下面的代码,并带有 -std=c++14 选项。

我希望它输出“1!” 因为转换是隐式的,但它输出“2!”。如果我注释掉模板构造函数,它将无法编译。这是正确的行为,还是某种 g++ 错误?

0 投票
2 回答
1020 浏览

c++ - 通过显式构造函数初始化数组

我正在编写一个具有带const char*参数的显式构造函数的类。对于这个问题的意图和目的,它看起来像这样:

现在我想编写一个用于初始化数组(数组/向量/列表——我不关心确切类型)的示例,并且我需要该示例尽可能清晰和简洁。理想情况下,它看起来像这样:

由于显式关键字而无法编译,我不准备将构造函数设为隐式。

我怎样才能完成这项工作,重点是使示例代码尽可能具有表现力?

编辑:在 Caleth 的帮助下,我选择了 Bolov 的解决方案:

0 投票
0 回答
402 浏览

c++ - 显式构造函数仍然允许隐式转换

我正在用 C++14 绘制一个小型通用类型包装模板,它旨在使用 mixins 启用、禁用或扩展底层类型的接口。

这是这个包装器的代码(精简了一点):

T现在,我可以使用以下 mixin-template 混合某种类型的构造形式:

到目前为止,这很好,例如我可以int这样包装:

在godbolt上查看完整代码。但是,我想禁用不需要的隐式转换,这就是我将构造函数标记为constructor_from::mixinas的原因explicit。但出乎意料的是,以下似乎仍然在 clang-5.0.0 上编译没有错误(参见compiler-explorer):

问题:

  • 这是 clang-5.0.0 中的错误吗?它似乎与gcc-7.3中的预期失败一起编译。
  • 如果它不是错误,我是否在这里做了一些不合理的事情(未定义,未指定,...),这解释了为什么尽管explicit在 clang-5.0.0 上有构造函数,它还是应该编译?或者我可能误解了构造函数继承的工作原理?

编辑:

正如@someprogrammerdude 指出的那样,我可能误解了这个explicit结构。但是,我仍然不明白为什么上面的代码应该编译,而没有:

如果有人能指出我在 c++ 标准中允许在 my 的情况下进行构造的相应部分,那就太好了wrapper,但在这种情况下阻止它

0 投票
2 回答
372 浏览

c++ - 为什么此 C++ 代码中的构造函数不明确,我该如何解决?

在下面的代码中,编译器无法确定我要使用哪个构造函数。为什么,我该如何解决这个问题?(现场示例

0 投票
1 回答
147 浏览

c++ - 复制构造函数和重载的加法运算符

我正在审查 C++ 中的运算符重载。只是为了好玩,我正在实施一个BigInt课程。

我要为其重载的第一个运算符是加法运算符。我决定将此运算符重载为友元非成员函数。这是此代码的 MWE:

这段代码模拟了加法的行为。它编译并运行。然而,当我为该类添加一个复制构造函数时BigInt,此代码停止工作。即,如果我将其添加到类声明中:

explicit BigInt(const BigInt &in): value_(in.value_) {}

代码甚至无法编译。编码的加法函数返回构造的实例的副本BigInt。为此,必须定义一个复制构造函数。如果我自己没有定义它,那么编译器会这样做。编译器会产生什么我没有通过添加的复制构造函数产生?这是我得到的编译错误:

从它看来,编译器似乎需要一个我没有提供的复制构造函数。现在...如果我删除explicit关键字,一切正常。但是,我已经看到了具有显式复制构造函数的实现,例如:Explicit copy constructor

我错过了什么?为什么我不能在重载加法运算符时使这个复制构造函数显式?一般来说,复制构造函数应该显式吗?

0 投票
1 回答
68 浏览

c++ - 避免在人为的模棱两可的重载函数调用中拼写出类型

最小示例程序:

直觉上,这是一个有效的程序是有意义的:使用重载#1 的调用将是有效的,使用重载#2 的调用将是格式错误的,因此应该选择重载#1。这就是 clang 所做的。

不幸的是,按照标准,这似乎是模棱两可的,因为有一个构造函数std::vector<void *>可以用 调用int,通过隐式将其转换为size_texplicit在重载决议期间应该忽略该构造函数的事实,如果选择该重载,程序将只是格式错误。GCC 以模棱两可的方式拒绝该呼叫,并且这样做看起来是正确的。

我可以修改代码,让 GCC 通过拼写类型名称来接受调用:f(std::vector<int>{ 1 });。我也可以使用带有默认参数的标签调度来明确指定要使用的重载,同时允许像以前一样接受现有调用。

这两个都是可以接受的,但是当回到真实代码时会很快变得相当冗长。是否有另一个选项可以让我避免拼出完整的类型名称,但坚持使用当前的重载?我想了一会儿{ 1, }可能会起作用,但当然它不会,int i = { 1, };也是完全有效的,不能用来避免#2。

如果有助于排除某些替代方案,则实际代码确实涉及std::vector<int>并且std::vector<T>确实涉及使用包含单个整数表达式的花括号初始化列表的调用,但T它是用户定义的类型,而不是内置类型,并且表达式是不是一个常数值。

“否”是可以接受的答案,但在这种情况下,请详细说明,请表明没有这样的选项。

0 投票
1 回答
132 浏览

c++ - C++:考虑但不调用构造函数的特殊性

在第二个意图(用于复制列表初始化)中关于列表初始化的 cppreference中,它说:

复制列表初始化(考虑显式和非显式构造函数,但只能调用非显式构造函数)

构造函数被“考虑”和实际“调用”的区别到底是什么。为什么要考虑构造函数,它可能无论如何都不会被调用?

0 投票
2 回答
195 浏览

c++ - 为什么 std::in_place_t 的构造函数默认且显式?

cppreference 显示以下定义std::in_place_t

为什么他们添加了一个explicit默认构造函数?为什么它没有被排除在外?有什么好处?

0 投票
0 回答
68 浏览

c++ - 通过显式调用使用参数化构造函数

我在编写这段代码时遇到了一个错误,所以在下面的程序代码中,obj1obj2是通过使用参数化构造函数显式调用的, 但是我无法得到输出说得到了错误。