Попытка изменить код из эта страница.
Вот код проблемы:
#include <iostream>
#include <array>
template<class T>
class const_reverse_wrapper
{
public:
const_reverse_wrapper (const T& cont)
: container_(cont)
{
}
decltype( container_.rbegin() ) begin() const
{
return container_.rbegin();
}
decltype( container_.rend() ) end()
{
return container_.rend();
}
private:
const T & container_;
};
template<class T>
class reverse_wrapper
{
public:
reverse_wrapper (T & cont)
: container_(cont)
{
}
decltype( container_.rbegin() ) begin()
{
return container_.rbegin();
}
decltype( container_.rend() ) end()
{
return container_.rend();
}
private:
T & container_;
};
template<class T>
const_reverse_wrapper<T> reversed (const T & cont)
{
return const_reverse_wrapper<T>(cont);
}
template<class T>
reverse_wrapper<T> reverse (T & cont)
{
return reverse_wrapper<T>(cont);
}
int main (int argc, char * argv[])
{
std::array<int,4> a = { 1, 2, 3, 4 };
for (int i : a)
std::cout << i;
return 0;
}
Когда я компилирую это, я получаю эти ошибки:
> g++ -std=c++0x test2.cpp
test2.cpp:13:15: error: 'container_' was not declared in this scope
test2.cpp:13:15: error: 'container_' was not declared in this scope
test2.cpp:18:15: error: 'container_' was not declared in this scope
test2.cpp:18:15: error: 'container_' was not declared in this scope
test2.cpp:36:15: error: 'container_' was not declared in this scope
test2.cpp:36:15: error: 'container_' was not declared in this scope
test2.cpp:41:15: error: 'container_' was not declared in this scope
test2.cpp:41:15: error: 'container_' was not declared in this scope
Когда я перемещаю частные разделы перед открытыми разделами в каждом классе, ошибки исчезают.
template<class T>
class const_reverse_wrapper
{
private: // <-----
const T & container_; // <-----
public:
const_reverse_wrapper (const T& cont)
: container_(cont)
{
}
decltype( container_.rbegin() ) begin() const
{
return container_.rbegin();
}
decltype( container_.rend() ) end()
{
return container_.rend();
}
};
template<class T>
class reverse_wrapper
{
private: // <-----
T & container_; // <-----
public:
reverse_wrapper (T & cont)
: container_(cont)
{
}
decltype( container_.rbegin() ) begin()
{
return container_.rbegin();
}
decltype( container_.rend() ) end()
{
return container_.rend();
}
};
Я попытался скомпилировать с MinGW GCC 4.6.2 и 4.7.0 и получить те же результаты. Это ошибка, или что-то еще происходит?
У вас была та же проблема до C ++ 11:
struct X{
Foo f(){ return 42; } // error: 'Foo' does not name a type
typedef int Foo;
};
Причина в том, что только тело функции-члена обрабатывается так, как если бы она была определена вне класса в отношении доступности члена.
§9.2 [class.mem] p2
Класс считается полностью определенным типом объекта (3.9) (или завершенным типом) при закрытии
}
из класса спецификатор. В классе член-спецификация, класс рассматривается как полный в функциональных телах, аргументы по умолчанию, исключение-технические характеристики, а также скобки или равно-инициализаторы для нестатических членов данных (включая такие вещи во вложенных классах). В противном случае он считается неполным в своем классе член-спецификация.
Таким образом, только имена, ранее замеченные внутри класса член-спецификация (как это называется в стандарте).
Я вижу два возможных исправления: одно для вашего конкретного варианта использования и общее. Для вашего конкретного случая просто используйте typename T::const_reverse_iterator
, Для общего случая используйте std::declval
получить объект определенного типа для decltype
и вызвать метод для этого:
#include <functional>
decltype(std::declval<T const&>().rbegin()) rbegin() const{ ... }
Других решений пока нет …