模板转换运算符的非常特殊行为的目的是什么?请考虑以下代码:
#include <iostream>
#include <utility>
#include <cstdlib>
#define PP { std::cout << __PRETTY_FUNCTION__ << std::endl; }
struct A
{
template< typename T >
operator T () { PP; return {}; }
template< template< typename ... > class C, typename ...types >
operator C< types... > () { PP; return {}; }
template< typename T >
T operator * () { PP; return {}; }
};
static void f(int) PP
template< typename T >
struct S {};
template< typename T = void >
void g(S< T >) PP
int main()
{
struct B {};
// T A::operator B() [T = B]
B{} = A{};
// C<types...> A::operator S() [C = S, types = <void>]
S< void >{} = A{};
// T A::operator int() [T = int]
// void f(int)
f(A{});
// void g(S<T>) [T = void]
g({});
// expected the same output prepended by "T A::operator S() [T = S<void>]"
// but conversion operator does not involved after first step when matching failed
// and default value of template parameter should be chosen to next try
// error: no matching function for call to 'g'
// note: candidate template ignored: could not match 'S<type-parameter-0-0>' against 'A'
//g(A{});
// error: indirection requires pointer operand ('A' invalid)
//B{} = *A{};
// error: no matching member function for call to 'operator*'
// note: candidate template ignored: couldn't infer template argument 'T'
//B{} = A{}.operator * ();
// error: indirection requires pointer operand ('A' invalid)
//(*A{}).~A();
return EXIT_SUCCESS;
}
就我所见,它能够自动推导出接收者所需的返回类型(赋值表达式的左侧或实际函数参数类型)是唯一的。我无法为一元operator *
,operator ->
,operator ()
和其他人重现此类行为。
我在隐式转换中找到了trick of how to know预期类型。