类 内的 C++ 函数重载
C++ function overloading within classes
我已经声明了一个 class 具有两个 operator() 函数的图像,一个用于只读,另一个用于读写访问。
此处摘录:
class Image {
//...
public:
uint16_t operator()(int x, int y) const
{
return data_[x + y*width_]; // read-only at pixle (x,y)
}
uint16_t & operator()(int x, int y)
{
return data_[x + y*width_]; // read/write to pixle (x,y)
}
//...
}
在此之后,我在 main() 函数中声明了一个 Image 对象并写入它(由于提到的 public Interface operator(),它必须工作),但是几个编译器只继续识别第一个只有读取权限的 operator() 函数。
示例:
if (count_alive_neighbors(image, i, j) == 3) {
image(i, j) = 255;
}
我的想法是,也许可以通过声明指针并更改值来解决这个问题。代码:
uint16_t* f = &image(i, j);
*f = 255;
在 Microsoft Visual Studio 2015 上,这首先在 if 循环之外单独进行了测试,但在刚刚提到的函数内部却没有。但这不是编译器错误,我已经用 Clang、g++ 和 MinGW 测试过了。
所有人都打印出这样的错误消息:
error: lvalue required as unary '&' operand
uint16_t* f = &(image(i, j));
^
总而言之,问题如下:如何通过不关注指针声明来解决这个问题,如何告诉编译器它必须使用哪个版本的 operator()?它自己无法识别它,或者我可能无法识别必须更改哪个 settings/code 才能使程序运行。
提前致谢。
编辑:整个class定义和函数
#include <vector>
#include <string>
#include <stdexcept>
#include <fstream>
#include <cstdint>
class Image
{
int width_;
int height_;
std::vector<uint16_t> data_;
public:
Image()
: width_(0)
, height_(0)
{}
Image(unsigned int width, unsigned int height)
: width_(width)
, height_(height)
, data_(width*height, uint16_t())
{}
int width() const
{
return width_;
}
int height() const
{
return height_;
}
int size() const
{
return width_*height_;
}
void resize(unsigned int new_width, unsigned int new_height)
{
data_.resize(new_width*new_height, uint16_t());
width_ = new_width;
height_ = new_height;
}
uint16_t operator()(int x, int y) const
{
return data_[x + y*width_];
}
uint16_t & operator()(int x, int y)
{
return data_[x + y*width_];
}
uint16_t get_periodic(int x, int y) const
{
int xres = x % width_;
int yres = y % height_;
return data_[xres + yres*width_];
}
};
int count_alive_neighbors(Image const & image, int x, int y) {
int res = 0;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (image.get_periodic(x + i, y + j) == 255) {
res += 1;
}
}
}
if (image.get_periodic(x, y) == 255) {
res -= 1;
}
}
Image conway_step(Image const & image) {
for (int i = 0; i <= image.width(); i++) {
for (int j = 0; j <= image.height(); j++) {
if (count_alive_neighbors(image, i, j) == 2)
{
}
if (count_alive_neighbors(image, i, j) == 3) {
image(i, j) = 255;
}
if (count_alive_neighbors(image, i, j) < 2) {
image(i, j) = 0;
}
if (count_alive_neighbors(image, i, j) > 3) {
image(i, j) = 255;
}
}
}
}
int main() {
Image img(3, 3); // declaring object
img(3, 3) = 255; /* !ATTENTION! this works, but inside
conway_steps it doesn't */
}
请更改您的函数签名
Image conway_step(Image const & image)
至
Image conway_step(Image & const image) //ill formed
或者更好的方式
Image conway_step(Image & image)
第一种情况,等价于const Image & image
,所以调用了const
限定运算符=>image(i, j)=255
; => uint16_t=255
=> left operand must be l-value
错误
在 second/third 情况下,您声明了对非 const 对象的 const 引用。
[根据评论] conway_step
应该复制其参数,修改该副本,然后 return 该副本。你的问题是你没有制作副本而试图修改原件。
我已经声明了一个 class 具有两个 operator() 函数的图像,一个用于只读,另一个用于读写访问。
此处摘录:
class Image {
//...
public:
uint16_t operator()(int x, int y) const
{
return data_[x + y*width_]; // read-only at pixle (x,y)
}
uint16_t & operator()(int x, int y)
{
return data_[x + y*width_]; // read/write to pixle (x,y)
}
//...
}
在此之后,我在 main() 函数中声明了一个 Image 对象并写入它(由于提到的 public Interface operator(),它必须工作),但是几个编译器只继续识别第一个只有读取权限的 operator() 函数。
示例:
if (count_alive_neighbors(image, i, j) == 3) {
image(i, j) = 255;
}
我的想法是,也许可以通过声明指针并更改值来解决这个问题。代码:
uint16_t* f = &image(i, j);
*f = 255;
在 Microsoft Visual Studio 2015 上,这首先在 if 循环之外单独进行了测试,但在刚刚提到的函数内部却没有。但这不是编译器错误,我已经用 Clang、g++ 和 MinGW 测试过了。
所有人都打印出这样的错误消息:
error: lvalue required as unary '&' operand
uint16_t* f = &(image(i, j));
^
总而言之,问题如下:如何通过不关注指针声明来解决这个问题,如何告诉编译器它必须使用哪个版本的 operator()?它自己无法识别它,或者我可能无法识别必须更改哪个 settings/code 才能使程序运行。
提前致谢。
编辑:整个class定义和函数
#include <vector>
#include <string>
#include <stdexcept>
#include <fstream>
#include <cstdint>
class Image
{
int width_;
int height_;
std::vector<uint16_t> data_;
public:
Image()
: width_(0)
, height_(0)
{}
Image(unsigned int width, unsigned int height)
: width_(width)
, height_(height)
, data_(width*height, uint16_t())
{}
int width() const
{
return width_;
}
int height() const
{
return height_;
}
int size() const
{
return width_*height_;
}
void resize(unsigned int new_width, unsigned int new_height)
{
data_.resize(new_width*new_height, uint16_t());
width_ = new_width;
height_ = new_height;
}
uint16_t operator()(int x, int y) const
{
return data_[x + y*width_];
}
uint16_t & operator()(int x, int y)
{
return data_[x + y*width_];
}
uint16_t get_periodic(int x, int y) const
{
int xres = x % width_;
int yres = y % height_;
return data_[xres + yres*width_];
}
};
int count_alive_neighbors(Image const & image, int x, int y) {
int res = 0;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (image.get_periodic(x + i, y + j) == 255) {
res += 1;
}
}
}
if (image.get_periodic(x, y) == 255) {
res -= 1;
}
}
Image conway_step(Image const & image) {
for (int i = 0; i <= image.width(); i++) {
for (int j = 0; j <= image.height(); j++) {
if (count_alive_neighbors(image, i, j) == 2)
{
}
if (count_alive_neighbors(image, i, j) == 3) {
image(i, j) = 255;
}
if (count_alive_neighbors(image, i, j) < 2) {
image(i, j) = 0;
}
if (count_alive_neighbors(image, i, j) > 3) {
image(i, j) = 255;
}
}
}
}
int main() {
Image img(3, 3); // declaring object
img(3, 3) = 255; /* !ATTENTION! this works, but inside
conway_steps it doesn't */
}
请更改您的函数签名
Image conway_step(Image const & image)
至
Image conway_step(Image & const image) //ill formed
或者更好的方式
Image conway_step(Image & image)
第一种情况,等价于const Image & image
,所以调用了const
限定运算符=>image(i, j)=255
; => uint16_t=255
=> left operand must be l-value
错误
在 second/third 情况下,您声明了对非 const 对象的 const 引用。
[根据评论] conway_step
应该复制其参数,修改该副本,然后 return 该副本。你的问题是你没有制作副本而试图修改原件。