以下代码在g ++ 5.1上运行正常,但在Visual Studio 2013或2015下运行时," R6025纯虚函数调用"在Test().GetCollection()
main()
时出错
#include <iostream>
template <typename T>
class MoveNextCollection
{
// Forward declaration
class ConstIterator;
public:
// Usual C++ collection typedefs
typedef T value_type;
typedef const value_type& const_reference;
typedef ConstIterator const_iterator;
const_iterator begin() const
{
if (MoveToStart(&_CurrentValue))
{
return const_iterator(this);
}
else
{
return end();
}
}
const_iterator end() const
{
return const_iterator();
}
virtual ~MoveNextCollection()
{
}
private:
class ConstIterator
{
public:
ConstIterator(const MoveNextCollection *pMoveNextCollection = nullptr)
: _pMoveNextCollection(pMoveNextCollection)
{
}
const_reference operator*() const
{
return _pMoveNextCollection->GetCurrentValue();
}
bool operator==(const ConstIterator &iter) const
{
return (_pMoveNextCollection == iter._pMoveNextCollection);
}
bool operator!=(const ConstIterator &iter) const
{
return !operator==(iter);
}
ConstIterator &operator++()
{
if (!_pMoveNextCollection->MoveToNext())
{
_pMoveNextCollection = nullptr;
}
return (*this);
}
private:
const MoveNextCollection *_pMoveNextCollection;
};
const_reference GetCurrentValue() const
{
return _CurrentValue;
}
bool MoveToNext() const
{
return MoveToNext(&_CurrentValue);
}
private:
virtual bool MoveToStart(value_type *) const = 0;
virtual bool MoveToNext(value_type *) const = 0;
mutable value_type _CurrentValue;
};
class Test
{
public:
class Collection : public MoveNextCollection<int>
{
private:
bool MoveToStart(int *pValue) const override
{
*pValue = 314; // Whatever
return true;
}
bool MoveToNext(int *) const override
{
return false;
}
};
const Collection& GetCollection() const
{
return _collection;
}
private:
Collection _collection;
};
int main()
{
for (int val : Test().GetCollection())
{
std::cout << val << "\n";
}
return 0;
}
但是,只有在类&#34; MoveNextCollection&#34;中的虚拟析构函数时才会出现这种情况。存在。否则运行正常(当析构函数被注释掉时)。请注意,上述错误发生在Visual Studio的桌面版本中,但如果您在http://webcompiler.cloudapp.net/运行代码,它只会显示错误-1073740791(我认为它的错误相同)。请注意,为了发布这个帖子,代码已经被删除了它的基本要点(对不起,不能让它更短)。这是VS的错误吗?对于任何反馈,我们都表示感谢。感谢。
答案 0 :(得分:2)
基于范围的表达式:
_playerLayer.player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
相当于:
for (int val : Test().GetCollection())
{
auto&& __range = Test().GetCollection(); // (1)
for ( auto __begin = begin(__range), // (2)
__end = end(__range);
__begin != __end;
++__begin )
{
int val = *__begin;
// etc
}
}
会返回对GetCollection()
的引用,但Test::_collection
对象超出了第(1)行中表达式末尾的范围 - 所以你要离开(2)悬挂的参考文献。之后的一切都是未定义的行为。它&#34;工作&#34;只是未定义行为的一种可能结果。
如果Test
看起来像:
GetCollection()
引用的临时绑定的生命周期将在引用的生命周期中延长,这将是整个基于范围的表达式。在该场景中没有未定义的行为。