Правка: ответ, который я отметил ниже, не на 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&()
не компилируется:
B<Bar> bBar(bar);
pBarData = bBar.data();
Кажется, что conditional
хочет скомпилировать оба аргумента шаблона, поэтому компиляция завершается ошибкой, когда T
не имеет operator&()
. Я пробовал разбрызгивать std::enable_if
, но безрезультатно.
using TPtr = decltype(&std::declval<int>());
. Я думал, что аргументdecltype
должен был быть неоцененным контекстом? Просто позвольте мне использовать&
, чтобы получить результирующий тип, черт возьми! - person Lightness Races in Orbit   schedule 17.06.2015std::declval<int>()
является значением x.&
можно использовать только для lvalue. - person T.C.   schedule 17.06.2015