下面的代码可以在Visual Studio中编译,但在gcc中失败。
template<typename Isth>
class A
{
public:
A(const boost::shared_ptr<Isth>& obj) {...}
...
};
在B组的方法中:
A<Isth1> B::method1
{
boost::shared_ptr<Isth2> myPtr = boost::make_shared<Isth2>();
//Isth2 is derived from Isth1;
...
return myPtr;
}
在gcc中,我收到错误“无法将'myPtr'从'boost :: shared_ptr'转换为'A'” 我认为应该在B :: method1返回时调用A的构造函数。
提前致谢!
答案 0 :(得分:5)
其他人强调了这个问题 - 如果shared_ptr<Isth2>
不需要用户定义的转换,A<Isth1>
只能转换为A<Isth1> B::method1()
{
boost::shared_ptr<Isth2> myPtr = boost::make_shared<Isth2>();
//Isth2 is derived from Isth1;
...
return { myPtr };
}
的构造函数参数。但是既然如此,就不能使用那个构造函数。
再次统一初始化有助于使这项工作
A
对于返回值的统一初始化,允许使用构造函数参数的用户定义的转换。如果您只想更改类template<typename T, typename std::enable_if<
std::is_base_of<Isth, T>::value, bool>::type = true>
A(const boost::shared_ptr<T>& obj) {...}
,您可能想要编写一些SFINAE
Isth
您基本上是在说明“我隐含地从指向派生自{{1}} 的对象的任何共享ptr进行转换。
答案 1 :(得分:1)
我很惊讶Visual Studio编译它。您期望如何返回shared_ptr而不是实际对象? shared_ptr<X>
无法转换为X。
好的,有些澄清是有道理的。这种转换需要自定义转换 - 一个从shared_ptr<Isth2>
到shared_ptr<Isth>
,另一个从shared_ptr<Isth>
到A.标准明确说明只允许一次自定义转换。海湾合作委员会是正确的。
至于Visual Studio为什么要转换它,我不确定。它要么急切地执行双重转换,要么不将shared_ptr转换视为自定义转换。我认为这两个选项都是错误的。
答案 2 :(得分:1)
您尝试在此处进行多次隐式转换:
boost::shared_ptr<Isth2>
- &gt; boost::shared_ptr<Isth1>
- &gt; A<Isth1>
正如C ++标准在12.3章转换中所述:
- 最多一个用户定义的转换(构造函数或转换 function)隐式应用于单个值。
醇>
这修复了编译:
A<Isth1> B::method1()
{
boost::shared_ptr<Isth2> myPtr = boost::make_shared<Isth2>();
//Isth2 is derived from Isth1;
...
return A<Isth1>(myPtr);
}
更新:
如果您不想修改返回值,可以修改A
类中的构造函数:
template <class Isth>
class A
{
...
template <class T> A(const boost::shared_ptr<T>&) { ... }
...
};