我被这个难倒......编译器输出:
d:\ data \ personal \ projects \ test \ test.cpp(42):错误C2105:' - '需要l值
#include <iostream>
#include <algorithm>
#include <iterator>
class FOO
{
public:
typedef int* iterator;
typedef const int* const_iterator;
class explicit_iterator : public std::iterator< std::bidirectional_iterator_tag, int >
{
public:
explicit_iterator(int* ptr = nullptr) : m_ptr(ptr) {}
bool operator ==(const explicit_iterator& rhs) const { return m_ptr == rhs.m_ptr; }
bool operator !=(const explicit_iterator& rhs) const { return m_ptr != rhs.m_ptr; }
reference operator *() const { return *m_ptr; }
explicit_iterator& operator ++() { ++m_ptr; return *this; }
explicit_iterator& operator --() { --m_ptr; return *this; }
private:
int* m_ptr;
};
FOO(int val = 0) { std::fill( begin(), end(), val ); }
iterator begin() { return m_data; }
iterator end() { return m_data + 10; }
explicit_iterator begin2() { return explicit_iterator( begin() ); }
explicit_iterator end2() { return explicit_iterator( end() ); }
private:
int m_data[10];
};
int main (int, char *[])
{
FOO foo;
// This is the line that fails! (Not this one, the one right below!!!)
std::copy( foo.begin(), --foo.end(), std::ostream_iterator<int>( std::cout, "\n" ) ); // C2105
// All these variants are good
std::copy( foo.begin2(), --foo.end2(), std::ostream_iterator<int>( std::cout, "\n" ) ); // good
std::copy( foo.begin(), foo.end() - 1, std::ostream_iterator<int>( std::cout, "\n" ) ); // good
int* end = foo.end();
std::copy( foo.begin(), --end, std::ostream_iterator<int>( std::cout, "\n" ) ); // good
return 0;
}
答案 0 :(得分:4)
您无法预先计算右值或指针类型。调用foo.end()
返回一个右值int*
,你无法预先增量/预先减少。{/ p>
下一个调用有效--foo.end2()
,因为在这种情况下,preincrement是一个成员函数,在语言中调用rvalue上的成员函数是合法的。语法等同于更明确的语法,这可能使其更容易理解:
foo.end2().operator--();
答案 1 :(得分:0)
此声明无效。
std :: copy(foo.begin(), - foo.end(),std :: ostream_iterator(std :: cout,“\ n”)); // C2105
函数foo.end()返回一个临时对象,您可能无法应用operator - 。
答案 2 :(得分:0)
预递减的操作数必须是内置类型(如指针)的可修改左值。参见C ++ 11 5.3.2&#34;递增和递减&#34;。
FOO::end()
成员函数返回一个内置类型(指针),它是一个右值,而不是一个可修改的左值,因此不能在其上使用预递减运算符。
FOO::end2()
返回一个右值,但不是内置类型。因此可以调用重载的预递减运算符。
最后,--end
正在对可修改的左值进行操作。