通过两个隐式构造函数构造一个值?
Constructing a value through two implicit constructors?
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
有效的方式更改代码?
您的第一个示例需要两个用户定义的转换才能编译 — SomeType -> Inner -> Outer
。但是,最多可以隐式应用一个用户定义的转换。
引用 N3337,§12.3 [class.conv]
1 Type conversions of class objects can be specified by constructors and by conversion functions. These conversions are called user-defined conversions and are used for implicit type conversions (Clause 4), for initialization (8.5), and for explicit type conversions (5.4, 5.2.9).
4 At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.
如果目标是避免在 return 语句中提及 Inner<SomeType>
,您可以使用列表初始化。
Outer<Inner<SomeType>> DoSomethingWorks2() {
SomeType value;
return {std::move(value)};
}
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
有效的方式更改代码?
您的第一个示例需要两个用户定义的转换才能编译 — SomeType -> Inner -> Outer
。但是,最多可以隐式应用一个用户定义的转换。
引用 N3337,§12.3 [class.conv]
1 Type conversions of class objects can be specified by constructors and by conversion functions. These conversions are called user-defined conversions and are used for implicit type conversions (Clause 4), for initialization (8.5), and for explicit type conversions (5.4, 5.2.9).
4 At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.
如果目标是避免在 return 语句中提及 Inner<SomeType>
,您可以使用列表初始化。
Outer<Inner<SomeType>> DoSomethingWorks2() {
SomeType value;
return {std::move(value)};
}