C ++ 0x decltype не может вывести константу переменной-члена - PullRequest
4 голосов
/ 09 февраля 2011

Рассмотрим следующий код:

template <typename T>
class B
{
};

template <typename T>
B<T> f(T& t)
{
    return B<T>();
}

class A
{
    class C {};
    C c;
public:
    A() {}

    decltype(f(c)) get_c() const { return f(c); }
};

int main()
{
    A a;
    a.get_c();
}

Когда я пытаюсь это скомпилировать, я получаю сообщение об ошибке:

test.cpp: In member function 'B<A::C> A::get_c() const':
test.cpp:31:46: error: conversion from 'B<const A::C>' to non-scalar type 'B<A::C>' requested

Похоже, что в decltype компилятор не знает, что это константная функция-член, и поэтому c имеет тип const C, и в результате неправильно выводит тип f(c) как 1010 *, а не B<const C>, который действительно есть.

Я что-то делаю неправильно, или это ошибка компилятора? Я использую gcc 4.6, но 4.4 и 4.5 показывают то же поведение.

Ответы [ 4 ]

7 голосов
/ 09 февраля 2011

Компилятор работает правильно в соответствии с текущим C ++ 0x WP. См. отчет об этой проблеме , над которым сейчас ведется работа.

Возможно, окончательный стандарт C ++ 0x не изменит значения вашего decltype приложения в типе возврата перед именем функции. Вам нужно будет переместить его после списка параметров, используя -> decltype(f(c)), что, будем надеяться, будет правильным в финальной версии C ++ 0x.

0 голосов
/ 09 февраля 2011

Я не думаю, что вам разрешено использовать decltype для всего, что вы обычно не могли бы вызвать.Я не смог найти в стандарте ничего, что позволило бы вам получить доступ к c, даже в выражении decltype, вне того места, где вы могли бы использовать c.Поскольку у вас нет указателя this в точке, где вы пытаетесь делать свое дело, я не думаю, что вы можете делать то, что пытаетесь сделать.Это не работает в MSVC 2010, по крайней мере, и не имеет ничего общего с const.

Я рассмотрел использование declval для получения единицы, но вы не можете получить доступ к A &&. C, поскольку A является неполнымэтот момент.Я все равно не вижу, что ты пытаешься делать, кроме как что-то вроде этого:

decltype(f(declval<C const>())) get_c() const { ... }
0 голосов
/ 09 февраля 2011

f должен принимать ссылку на rvalue, а не ссылку на lvalue.

0 голосов
/ 09 февраля 2011

Нет, decltype не должен учитывать, является ли функция константной или нет, потому что не может. То же самое можно было бы написать по-другому:

typedef decltype(f(c)) return_type;

return_type get_c() const { return f(c); }

Исправление: decltype(f(c)) даже не должно компилироваться, потому что c не является статичным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...