得到&的类型内置和运算符&()?

时间:2015-06-17 16:29:39

标签: c++ templates operator-overloading template-meta-programming addressof

修改:我在下面标记的答案并非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_ofis_call_possible之后建模。然后是客户端代码

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

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

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

似乎conditional想要编译两个模板参数,因此当T没有operator&()时编译失败。我试过在std::enable_if附近洒水,但无济于事。

1 个答案:

答案 0 :(得分:1)

您可以使用decltypedeclval来强行将左值传递给&运算符(这是必需的):

#include <utility>开始,定义以下帮助函数:

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

然后:

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

live demo