TLDR :我有两个模板化的课程Outer
和Inner
。可以从Inner<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
的方式更改?
答案 0 :(得分:6)
您的第一个示例需要两个用户定义的转换才能进行编译 - SomeType -> Inner -> Outer
。但是,最多可以隐式应用一个用户定义的转换。
引用N3337,§12.3[class.conv]
1类对象的类型转换可以由构造函数和转换函数指定。这些转换称为用户定义的转换,用于隐式类型转换(第4节),初始化(8.5)和显式类型转换(5.4,5.2.9)。
4最多一个用户定义的转换(构造函数或转换函数)隐式应用于单个值。
如果目标是避免在return语句中提及Inner<SomeType>
,则可以使用列表初始化。
Outer<Inner<SomeType>> DoSomethingWorks2() {
SomeType value;
return {std::move(value)};
}