【问题标题】:Constructing a value through two implicit constructors?通过两个隐式构造函数构造一个值?
【发布时间】:2015-05-19 01:19:27
【问题描述】:

TLDR:我有两个模板化类OuterInnerInner<X> 可以从X 隐式构造,Outer<Y> 可以从Y 隐式构造。 Outer<Inner<X>> = X() 应该工作吗?

更多详情:

假设我有以下两个类:

template<typename T> 
class Inner {
  public: 
    Inner(const T& value) {}
    Inner(T&& value) {}
};

template<typename T>
class Outer {
  public:
    Outer(const T& value) {}
    Outer(T&& value) {}
};

考虑以下函数:

struct SomeType{};
Outer<Inner<SomeType>> DoSomethingFails() {
  SomeType value;
  return value;      
}

g++ 抱怨:

no viable conversion from 'SomeType' to 'Outer<Inner<SomeType> >'
note: candidate constructor not viable: no known conversion from 'SomeType' to 'const Inner<SomeType> &' for 1st argument

但如果我改为执行以下操作:

Outer<Inner<SomeType>> DoSomethingWorks() {
  SomeType value;
  return Inner<SomeType>(value);      
}

它有效。期望DoSomethingFails 工作是否合理?如果不是,为什么?并且可以以DoSomethingFails 工作的方式更改代码吗?

【问题讨论】:

    标签: c++ constructor implicit


    【解决方案1】:

    您的第一个示例需要两个用户定义的转换来编译 - SomeType -&gt; Inner -&gt; Outer。但是,最多可以隐式应用一个用户定义的转换。

    引用 N3337,§12.3 [class.conv]

    1 类对象的类型转换可以由构造函数和转换函数指定。这些转换称为用户定义的转换,用于隐式类型转换(第 4 条)、初始化(8.5)和显式类型转换(5.4、5.2.9)。

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


    如果目标是避免在 return 语句中提及Inner&lt;SomeType&gt;,则可以使用列表初始化。

    Outer<Inner<SomeType>> DoSomethingWorks2() {
      SomeType value;
      return {std::move(value)};
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-11
      • 2012-09-20
      • 2020-02-13
      • 1970-01-01
      相关资源
      最近更新 更多