简体   繁体   English

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

[英]How to disable implicit constructor conversion, while allowing copy-initialization

Assuming we have something like: 假设我们有类似的东西:

class U {
  ...
}

and: 和:

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

Now I can declare a variable like so: U foo; 现在我可以像这样声明一个变量: U foo; then T blah(foo); 然后T blah(foo); or T blah = foo 或者T blah = foo

Personally I prefer the later. 我个人更喜欢后者。

Now, should I change the T copy constructor to: 现在,我应该将T拷贝构造函数更改为:

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

I can only declare a variable like: T blah(foo); 我只能声明一个变量: T blah(foo); T blah = foo; will give me a compilation error about the impossibility to convert U to T. 会给我一个关于将U转换为T的不可能性的编译错误。

http://en.cppreference.com/w/cpp/language/explicit explains that behaviour with: "Specifies constructors and (since C++11) conversion operators that don't allow implicit conversions or copy-initialization ." http://en.cppreference.com/w/cpp/language/explicit解释了这种行为:“指定构造函数和(自C ++ 11以来)不允许隐式转换或复制初始化的转换运算符。”

Now, the folks I work for require that all our constructors are made explicit. 现在,我工作的人要求我们所有的构造函数都是明确的。 Being an old fart, I don't like changing my coding style too much and forget about T blah = ... style. 作为一个老屁,我不喜欢太多改变我的编码风格而忘记T blah = ...风格。

The question as such is this: "Is there a way to make a constructor explicit while allowing copy-initialization syntax?" 这样的问题是:“有没有办法在允许复制初始化语法的同时使构造函数显式化?”

There are very good reasons to make a constructor explicit, and most of the time, you do want to make it explicit. 将构造函数显式化是有充分理由的,而且大多数情况下,您确实希望将其显式化。

Under those instances, I thought I could do something along the line of: 在这些情况下,我认为我可以做以下事情:

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

Which would be a catch-all constructor forbidding all conversion but the one I actually want. 这将是一个全能的构造函数,禁止所有转换但我真正想要的转换。

Was wondering if there was some trick I could use. 想知道是否有一些我可以使用的技巧。

Thanks 谢谢

Edit: corrected the typo as pointed by Matt McNabb answer. 编辑:纠正了Matt McNabb回答的错字。 thanks 谢谢

T blah = U(); gives the error because, as you correctly explain, copy-initialization calls for implicit conversion of U to T ; 给出错误,因为正如您正确解释的那样,复制初始化调用将U隐式转换为T ; but you have marked the constructor explicit . 但是你已经explicit标记了构造explicit (Note: this is not a copy constructor) (注意:这不是复制构造函数)

Explicit conversion would look like T blah = T(U()); 显式转换看起来像T blah = T(U()); and this should work with no errors. 这应该没有错误。

T blah(U()); is a function declaration (look up most vexing parse ). 是一个函数声明(查找最令人烦恼的解析 )。 You probably didn't actually try to use blah as if it were an object, in your test case, otherwise you would have noticed this problem. 在你的测试用例中,你可能实际上并没有尝试使用blah ,就好像它是一个对象,否则你会注意到这个问题。


Moving onto your question: 转到你的问题:

Is there a way to make a constructor explicit while allowing copy-initialization syntax? 有没有办法在允许复制初始化语法的同时使构造函数显式化?

There is not, as explained by the exact text you quoted about explicit : 没有,正如你引用的关于explicit的确切文字所解释的那样:

Specifies constructors [...] that don't allow [...] copy-initialization. 指定不允许复制初始化的构造函数[...]。

You'll have to switch to direct or braced initialization. 您必须切换到直接或支持初始化。 IMHO that's a good thing anyway, copy-initialization is cumbersome and only good for avoiding MVPs; 恕我直言,这是一件好事,复制初始化很麻烦,只对避免MVP有好处; but now that we can avoid MVPs using braced initialization, it's no longer necessary at all. 但现在我们可以避免使用支撑初始化的MVP,它根本不再需要。

You could use either of the following, which work because in all cases a T is directly and explicitly initialized by the list element: 您可以使用以下任一方法,因为在所有情况下, T都由list元素直接显式初始化:

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

Note that T blah = { U() }; 注意T blah = { U() }; cannot be used here because that form of initialization (known as copy-list-initialization ) cannot use an explicit constructor. 这里不能使用,因为这种初始化形式(称为copy-list-initialization )不能使用显式构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在c ++中使用隐式转换进行复制初始化 - Copy-initialization with implicit conversion in c++ 在复制初始化中,对复制构造函数的调用是显式还是隐式的? - In copy-initialization, is the call to the copy constructor explicit or implicit? 复制构造函数是否不用于复制初始化或优化? - Copy constructor is not called for copy-initialization or optimized? 转换运算符绕过派生类型的构造函数并跳过基类型的复制初始化? - conversion operator bypasses constructor of the derived type and skips to copy-initialization of the base type? 在复制初始化期间不会发生std :: string的隐式构造 - Implicit construction of std::string does not happen during copy-initialization 私有复制构造函数/赋值运算符和复制初始化 - private copy constructor/assignment operator and copy-initialization 为什么这种复制初始化(带有两个隐式转换)在 GCC/Clang 中不起作用? - Why this copy-initialization (with two implicit conversions) does not work in GCC/Clang? 复制初始化的奇怪行为,不调用复制构造函数! - Strange behavior of copy-initialization, doesn't call the copy-constructor! 它是直接初始化还是复制初始化? - Is it direct-initialization or copy-initialization? 复制构造函数隐式转换问题 - Copy constructor implicit conversion problem
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM