获取内置运算符&()的&的类型?

Get the type of & for built-in and operator&()?

编辑: 我在下面标记的答案并非 100% 正确,实际上是在评论中:using TPtr = decltype(&std::declval<T&>());


我正在尝试使用 std::conditional<> 获取 &T 的类型,其中 T 可能有 operator&(),也可能没有。

简单的解决方案是甚至不尝试,而是指定另一个模板参数:

struct Foo
{
    int operator&() { return 314; }
};

struct Bar { };

template <typename T, typename TPtr = T*>
struct A
{
    T& _t;
    A(T& t) : _t(t) {}
    TPtr data() {
        return &_t;
    }
};

客户端代码在哪里

Foo foo;
A<Foo, int> aFoo(foo);
int pFooData = aFoo.data();

Bar bar;
A<Bar> aBar(bar);
Bar* pBarData = aBar.data();

但我更想写的是:

template <typename T>
struct B
{
    using TPtr = typename std::conditional<has_operator_address_of<T>::value, typename std::result_of<decltype(T::operator&)&()>::type, T*>::type;

    T& _t;
    B(T& t) : _t(t) {}
    TPtr data() {
        return &t;
    }
};

其中 has_operator_address_of 模仿 is_call_possible。然后是客户端代码

B<Foo> bFoo(foo); // no need to second template argument
pFooData = bFoo.data();

但是没有 operator&() 的 class 无法编译:

B<Bar> bBar(bar);
pBarData = bBar.data();

似乎 conditional 想编译两个模板参数,所以当 T 没有 operator&() 时编译失败。我试过在周围喷洒 std::enable_if,但无济于事。

您可以使用 decltypedeclval,通过一些技巧强制将 lvalue 传递给 & 运算符(这是必需的):

#include <utility>开始,定义如下辅助函数:

template <typename T>
T& as_lvalue(T&& val)
{
    return val;
}

然后:

using TPtr = decltype(&as_lvalue(std::declval<T>()));

(live demo)