[英]Compile error despite override
抱歉,如果這是一個簡單的問題,那么對於c ++中的繼承, virtual
和override
,肯定有一些我不了解的地方。 在下面的示例中,我得到了一個與虛擬方法相關的編譯時錯誤,我專門重寫了該方法以避免子類發生此類錯誤。 難道我做錯了什么?
#include <array>
#include <deque>
template <class T, class C>
struct foo
{
virtual const C& data() const =0;
inline virtual T& operator[] ( unsigned n ) const
{ return const_cast<T&>( data()[n] ); }
};
/**
* The implementation of foo::operator[] is useful for classes inheriting
* with simple sequence containers like:
* foo<T,std::deque<T>>, foo<T,std::vector<T>>, ..
*
* But the following requires operator[] to be redefined:
*/
template <class T, unsigned N>
struct baz
: public foo<T, std::deque<std::array<T,N>> >
{
typedef std::deque<std::array<T,N>> data_type;
data_type m_data;
inline const data_type& data() const
{ return m_data; }
inline virtual T& operator[] ( unsigned n ) const override
{ return const_cast<T&>( data()[n/N][n%N] ); }
};
int main()
{
baz<double,3> b; // throws an error relative to foo::operator[] depsite override
}
編輯1錯誤:
clang++ -std=c++0x -Wall virtual_operator.cpp -o virtual_operator.o
virtual_operator.cpp:11:12: error: const_cast from 'const value_type' (aka 'const std::__1::array<double, 3>') to 'double &' is not allowed
{ return const_cast<T&>( data()[n] ); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~
virtual_operator.cpp:26:8: note: in instantiation of member function 'foo<double, std::__1::deque<std::__1::array<double, 3>, std::__1::allocator<std::__1::array<double, 3> > > >::operator[]'
requested here
struct baz
^
1 error generated.
編輯2我認為這是問題的一部分; 如果由於foo::operator[]
在baz
仍可調用而導致編譯失敗,那么如果我不將 foo::operator[]
聲明為虛擬的(即隱藏而不是覆蓋),為什么它編譯正常?
問題是,盡管您只打算在baz
實例上調用派生的operator[]
函數,但是編譯器仍需要為基類生成代碼,因為該函數仍可在baz
實例上調用。 在這種情況下,生成該代碼會導致類型錯誤,因為您正在嘗試將const std::array<double,3>
轉換為double&
。
為了解決這個問題,您應該在層次結構的不同部分定義一個運算符,該運算符將對其所有子運算符起作用,如下所示(除去了非永久性的東西):
template <class T, class C>
struct foo
{
inline virtual T& operator[] ( unsigned n ) const = 0;
};
template <class T>
struct bar
: public foo<T,std::deque<T>>
{
inline virtual T& operator[] ( unsigned n ) const override
{ return const_cast<T&>( data()[n] ); }
};
template <class T, unsigned N>
struct baz
: public foo<T, std::deque<std::array<T,N>> >
{
inline virtual T& operator[] ( unsigned n ) const override
{ return const_cast<T&>( data()[n/N][n%N] ); }
};
這樣,如果您要在以后添加任何其他版本,則可以從bar或baz派生,而無需為每個孩子定義運算符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.