Как я могу использовать decltype, чтобы получить тип ссылки? - PullRequest
4 голосов
/ 11 февраля 2011

Я работаю над кодом, используя decltype в CodeGear RAD Studio. Я пробовал наивное решение, которое выглядит не так, как это:

int main(int, char**) {
    int i;
    int &ir = i;
    decltype((ir)) ir_clone = ir;
}

Конечно, это не скомпилируется: Внутренняя ошибка компилятора. Я скорее подозреваю, что в этом коде нет ничего особенно плохого и есть ошибка компилятора в отношении выражений ссылок. (Между прочим, g ++ не имеет проблем с кодом и прекрасно его компилирует.) Однако это не помогает решить проблему, поскольку платформа не подлежит обсуждению.

Если выше, я написал

    decltype(ir) ir_clone = ir; /* No extra parens */

компилируется и работает как положено. Однако проблема на этом не заканчивается, так как это не правильно вычисляет константу из среды. В частности:

struct S { int i; } s;
const S* p = &s;
decltype(p->i)   i0 = s.i; /* i0 is an int */
decltype((p->i)) i1 = s.i; /* i1 is a const int& */

Если я не использую парены, чтобы сделать аргумент выражением, я теряю постоянство аргумента, которое мне нужно.

Еще один инструмент, который я могу использовать, - это простые шаблоны, например:

template<class T> struct unref     { typedef T type; }
template<class T> struct unref<T&> { typedef T type; }

Это позволяет мне удалить справочную часть типа, используя unref<int&>::type.

То, что я не могу понять, это как собрать все эти инструменты вместе, чтобы получить успешное выражение для нужного мне типа. Для одной из вещей, которые мне нужны, я работаю над обобщенным макросом, который делает «foreach». (Да, я знаю, что Boost делает это лучше.) Он должен обрабатывать следующие сценарии:

(vector<int>) vi          => vector<int>
(vector<int>&)vir         => vector<int>
(const vector<int>) cvi   => const vector<int>
(const vector<int>&)cvir  => const vector<int>
(const P*) cp->vi         => const vector<int>
(P*) p->vi                => vector<int>

Пока что мои простые попытки терпят неудачу:

unref<decltype(cp->vi)>   /* is vector<int>, not what I need. */
unref<decltype((cp->vi))> /* is const vector<int>, which is right. */

unref<decltype(vir)>      /* is vector<int>, which is right. */
unref<decltype((vir))>    /* Internal Compiler Error, which is a headache. */

Есть идеи, чтобы вывести меня на правильный путь? Надеюсь, я просто скучаю по чему-то простому. Может быть, я атакую ​​проблему под неправильным углом.

Ответы [ 2 ]

2 голосов
/ 20 июня 2016

Вы можете использовать std :: remove_reference (см. http://en.cppreference.com/w/cpp/types/remove_reference).

2 голосов
/ 11 февраля 2011

Попробуйте создать другое, более сложное выражение, которое приведет к тому же типу, который вы хотите, например:

decltype((void(), ir))

Я не могу сказать вам, почему оно это исправляет, но иногда другое выражение будетсделать трюк.

...