mercredi 28 janvier 2015

Strange compiler error when using decltype in visual studio 2013


template <typename Iter>
class CircularIterator
{
public:
CircularIterator(Iter it, Iter end) : _curr(it), _begin(it), _end(end)
{
if (it == end)
{
throw std::runtime_error("Cannot create CircularIterator for empty range.");
}
}

CircularIterator(const CircularIterator& other) :
_curr(other._curr),
_begin(other._begin),
_end(other._end)
{
// Do nothing.
}

CircularIterator& operator=(const CircularIterator& other)
{
CircularIterator copy(other);

Swap(copy);

return *this;
}

template <typename Y>
void Swap(CircularIterator<Y>& other)
{
using std::swap;

swap(_curr, other._curr);
swap(_begin, other._begin);
swap(_end, other._end);
}

auto operator*() -> decltype(((Iter*)nullptr)->operator*())
{
return *_curr;
}

auto operator->() -> decltype(_curr.operator->())
{
return _curr.operator->();
}

void Next()
{
++_curr;
if (_curr == _end)
{
_curr = _begin;
}
}

private:
Iter _curr;
Iter _begin;
Iter _end;
};

template <typename T>
auto CreateCircularIterator(T& container) -> CircularIterator<decltype(begin(container))>
{
return CircularIterator<decltype(begin(container))>(begin(container), end(container));
}

void foo()
{
const size_t numBuffers = 2;
vector<vector<char>> buffers(numBuffers);

auto bufferIter = CreateCircularIterator(buffers);
void* buffPtr = bufferIter->data(); // Error here
}


I'm getting the error error C2839: invalid return type 'int' for overloaded 'operator ->' on that last line, but it goes away if I change the signature of the operator-> overload to auto operator->() -> decltype(((Iter*)nullptr)->operator->())


Is this a compiler bug? Or am I misunderstanding how to use decltype?


Aucun commentaire:

Enregistrer un commentaire