1

編集:以下にマークした答えは100%正しいわけではありません。実際にはコメントにあります:using TPtr = decltype(&std::declval<T&>());


std::conditional<>のタイプを取得するため&Tに使用しようとしてToperator&()ます。

簡単な解決策は、試すことすらせず、代わりに別のテンプレート引数を指定することです。

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&()はコンパイルに失敗します:

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

conditional両方のテンプレート引数をコンパイルしたいようですので、コンパイルは失敗Tしますoperator&()。散らかしてみましstd::enable_ifたが、だめでした。

4

1 に答える 1

1

decltypeanddeclvalを少しハックして使用して、左辺値を強制的に演算子に渡すことができます&(これは必須です)。

#include <utility>次のヘルパー関数から始めて定義します。

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

それで:

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

(ライブデモ)

于 2015-06-17T16:47:09.690 に答える