给定以下转换运算符
struct A
{
template<typename T> explicit operator T&& () &&;
template<typename T> explicit operator T& () &;
template<typename T> explicit operator const T& () const&;
};
struct B {};
我希望以下转换都是有效的,但有些会产生编译错误(现场示例):
A a;
A&& ar = std::move(a);
A& al = a;
const A& ac = a;
B&& bm(std::move(a)); // 1. OK
B&& bt(A{}); // 2. OK
B&& br(ar); // 3. error: no viable conversion from A to B
B& bl(al); // 4. OK
const B& bz(al); // 5. OK
const B& bc(ac); // 6. OK
B cm(std::move(a)); // 7. error: call to constructor of B ambiguous
B ct(A{}); // 8. error: call to constructor of B ambiguous
B cr(ar); // 9. OK
特别是,1 似乎与 3 相同,并且与 2 几乎相同(对于 7 到 9、8 类似),但行为不同。
任何解释或解决方法?
我的动机是又一个 'any',我最终不得不让所有的转换运算符explicit
来避免像std::is_constructible
,这样的类型特征的问题std::is_convertible
,然后我遇到了新的问题。
编辑对不起,请忽略 3 和 9,我的错误(感谢 Kerrek SB)。然而 7 和 8 仍然是问题。另外,explicit
毕竟似乎无关紧要,再次抱歉。
编辑 2刚刚注意到
B cm = std::move(a);
B ct = A{};
如果转换运算符不是 ,则有效explicit
。所以这就是explicit
出现的地方:最初我的示例使用复制初始化,当我切换到时,explicit
我不得不使用直接初始化。然后出现了这个问题(案例 7 和 8)。