gpt4 book ai didi

c++ - 如何禁用隐式构造函数转换,同时允许复制初始化

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:40:24 27 4
gpt4 key购买 nike

假设我们有类似的东西:

class U {
...
}

和:

class T {
T(const U&) { ... }
}

现在我可以像这样声明一个变量:U foo; 然后 T blah(foo);T blah = foo

我个人更喜欢后者。

现在,我应该将 T 复制构造函数更改为:

class T {
explicit T(const U&) { ... }
}

我只能像这样声明一个变量:T blah(foo); T blah = foo; 会给我一个关于无法将 U 转换为 T 的编译错误。

http://en.cppreference.com/w/cpp/language/explicit用以下方式解释该行为:“指定不允许隐式转换或复制初始化的构造函数和(自 C++11 起)转换运算符。”

现在,我工作的人要求我们所有的构造函数都是显式的。作为一个老屁,我不喜欢过多地改变我的编码风格而忘记 T blah = ... style。

问题是这样的:“有没有办法在允许复制初始化语法的同时使构造函数显式化?”

有充分的理由使构造函数显式化,而且大多数时候,您确实想要使其显式化。

在那些情况下,我认为我可以做一些事情:

class T {
template<typename = V>
T(const V&) = delete;
T(const U&) { ... }
}

这将是一个包罗万象的构造函数,除了我真正想要的以外,禁止​​所有转换。

想知道我是否可以使用一些技巧。

谢谢

编辑:更正了 Matt McNabb 回答中指出的错字。谢谢

最佳答案

T blah = U(); 给出错误,因为正如您正确解释的那样,复制初始化调用隐式转换 UT;但您已将构造函数标记为 explicit。 (注意:这不是拷贝构造函数)

显式转换看起来像 T blah = T(U());,这应该没有错误。

T blah(U()); 是一个函数声明(查找 most vexing parse )。在您的测试用例中,您可能实际上并没有尝试将 blah 当作一个对象来使用,否则您会注意到这个问题。


继续你的问题:

Is there a way to make a constructor explicit while allowing copy-initialization syntax?

正如您引用的有关 explicit 的确切文本所解释的那样:

Specifies constructors [...] that don't allow [...] copy-initialization.

您必须切换到直接初始化或支撑初始化。恕我直言,无论如何这是一件好事,复制初始化很麻烦,而且只对避免 MVP 有好处;但现在我们可以使用花括号初始化来避免 MVP,所以根本就没有必要了。

您可以使用以下任一方法,因为在所有情况下 T 都由列表元素直接明确地初始化:

T blah{ U() };
T blah = T{ U() }; // redundant copy/move operation, probably elided

请注意 T blah = { U() }; 不能在这里使用,因为这种初始化形式(称为 copy-list-initialization)不能使用显式构造函数。

关于c++ - 如何禁用隐式构造函数转换,同时允许复制初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30022917/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com