为什么隐式转换在g ++中不起作用

时间:2015-11-18 19:20:27

标签: c++ gcc

下面的代码可以在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的构造函数。

提前致谢!

3 个答案:

答案 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章转换中所述:

  
      
  1. 最多一个用户定义的转换(构造函数或转换   function)隐式应用于单个值。
  2.   

这修复了编译:

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>&) { ... }
    ...
};