C++ 为什么不是';在这种情况下,是否调用了最合适的构造函数?
考虑以下类别:C++ 为什么不是';在这种情况下,是否调用了最合适的构造函数?,c++,constructor,type-conversion,copy-constructor,enable-if,C++,Constructor,Type Conversion,Copy Constructor,Enable If,考虑以下类别: class-foo{ int数据; 公众: 模板 foo(const T&i):数据{i}{cout之所以发生,是因为操作符int() 由于operator int(),obj1调用operator int(),并将自身转换为int 可能的解决办法: 使用static\u cast。这将把通常应转换为int的变量转换为foo 任何人请编辑这个问题,并填写这个。我没有更多的想法 您的模板“move”构造函数(带有T=foo&)有一个foo&类型的参数,它比您的复制构造函数更匹配,
class-foo{
int数据;
公众:
模板
foo(const T&i):数据{i}{cout之所以发生,是因为操作符int()
由于operator int()
,obj1
调用operator int()
,并将自身转换为int
可能的解决办法:
使用static\u cast
。这将把通常应转换为int
的变量转换为foo
任何人请编辑这个问题,并填写这个。我没有更多的想法
您的模板“move”构造函数(带有T=foo&
)有一个foo&
类型的参数,它比您的复制构造函数更匹配,因为它只需要const foo&
。然后,您的模板构造函数通过将i
转换为int
,调用操作符int()
最简单的即时修复方法是使用enable_if
来限制移动构造函数移动操作:如果T
被推断为左值引用类型(意味着你的T&&i
也将塌陷为左值引用),则强制替换失败
template <typename T, typename = enable_if_t<is_constructible<int, T>::value>,
typename = enable_if_t<!is_lvalue_reference<T>::value>>
foo(T&& i) : data( std::move(i) ) { cout << "Value move ctor" << endl; }
这将替换您的值复制和值移动构造函数
另一个注意事项:is_constructible::value
是一个测试,它告诉您数据(std::forward(i))
是否格式正确。它不测试数据{std::forward(i)}
格式良好。结果不同的T
是long
,因为long
到int
的转换是窄化转换,并且{}中不允许窄化转换
它是否应该是可构造的,而不是像您现在所拥有的那样是可构造的?@Alejandro,这也是正确的。@nwp我很困惑。根据,该东西返回第一个东西是否可以从第二个东西构造。由于我正在构造我的数据
成员(它是int
)从T
参数来看,这应该是正确的顺序。我只接受可以从中构造int
的类型。您所说的确实解决了问题,但我现在比以前更困惑了:dwat@Alejandro所说的只起作用,因为在示例中T是int。如果您将数据声明为任何非原始类型(称之为酒吧)而int不能从bar中构造,那么这些构造函数将被排除在is_constructible之外,因为对于t:int,int没有从bar中构造自身的可见方法。但是,如果bar声明一个接受int的公共构造函数,那么t:int的is_constructible将成功。如果我错误地解释了用法,请纠正我。什么@alejandro说的也是真的。我知道为什么可能,但问题是为什么会这样。因为有一个构造函数接受参数的确切类型(foo
),不应进行转换。如果类没有接受foo
对象的构造函数,这将是完全正常的,但既然它接受了,那么这应该是一个比触发转换更简单的途径。此外,static\u cast
也不能解决问题。我传入的值已经是foo类型代码>,不需要强制转换它。那么也许您可以生成一个操作符foo()
所以我的问题是,我将foo
对象传递给一个函数,该函数确实有一个重载,用于foo
参数,但这不是被调用的重载。呃,我真的很困惑。这似乎是一个可能的解决方案,但我不确定你的意思。你能解释得更好一点吗?这很有效!我不知道右值引用可以以任何方式折叠为左值引用。谢谢!您添加的其他内容也非常有用。我没有想到其中的一些内容。谢谢我刚才看了talk…现在一切都有意义:)Herb在演讲的最后一节中谈到了完美的转发T&
。我希望我能早点看这个。
template <typename T, typename = enable_if_t<is_constructible<int, T>::value>
, typename = enable_if_t<!is_same<decay_t<T>, foo>::value>
foo(T&& i) : data( std::forward<T>(i) ) { cout << "Forwarding ctor" << endl; }