尽管覆盖,但编译错误
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 派生,而无需为每个子级定义运算符。
相关文章:
- std::is_base_of表示ctor编译错误
- Qt5:使用QCommandLineParser类时出现奇怪的编译错误
- 如何修复sfml c++代码编译错误
- 使用 MATLAB 编码器生成C++代码:编译错误"undefined reference to `rgb2gray_tbb_real64'"
- 使用外部SDK工具链文件在VisualStudio上生成项目编译错误
- vscode下的Arduino代码出现意外编译错误
- 第三方 API 中的编译错误 - Visual Studio
- std::cout输出int时出现编译错误
- 奇怪的代码抛出编译错误模板< J,int aSize=10> C2143:语法错误:在"<"之前缺少";"
- 提升图广度优先搜索前置编译错误
- C++ 中的编译错误:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- 使用带有 ref 参数的成员函数创建线程时出现编译错误
- 我在C++中遇到了这个奇怪的编译错误
- 在C++中使用 Catch 测试框架编译错误"error: expected ';' at end of declaration list"
- 使用 std::enable_if 限制派生类的模板参数时出现编译错误
- 现代OpenGL和GLEW Libraray的编译错误
- C++ 编译错误:意外的类型名称"字符串":预期的表达式
- C ++程序编译错误,找不到/访问文件
- 使用直接大括号初始化时,C++ 编译错误"声明末尾的预期";"
- 为什么传递非静态成员函数会导致编译错误?