给定一个指向 C++ 对象的指针,有哪些正确的方式可以调用 operator[] 函数?

3

我正在使用模板编写一个时间变化的配置文件类,并且希望通过数值索引或struct tm表示的日期和时间进行索引。数值索引可以正常工作,但是使用指向对象的日期索引无法正常工作。以下是一些包含可行和不可行方法的样例代码。

#include "profile.h" // Class Profile<T> is declared and defined here.
float f;
int i;
struct tm d;
Profile<float> p;
Profile<float> *pPtr;

// Non-pointer syntax
f = p[i];                // this works.
f = p.operator[](i);     // this works, but its ugly.
f = p[d];                // this works.
f = p.operator[](d);     // this works, but its ugly.

// Pointer syntax
f = (*pPtr)[i];          // this works.
f = pPtr->operator[](i); // this works, but its ugly.
f = (*pPtr)[d];          // this isn't what I typed.  I did f = *(pPtr)[d];
f = pPtr->operator[](d); // this works, but its ugly.

这段C++代码是在Visual Studio 2008中编写的。编译器错误提示为 error C2677 binary '[' : no global operator found which takes type 'tm' (or there is no acceptable conversion).

给定一个C++对象的指针,调用 operator[] 函数的所有正确方式有哪些?


2
f = (*pPtr)[d]; // this doesn't work. 我敢肯定它是可以工作的;你看到了什么错误? - ildjarn
你是说 (*pPtr)[d] 不能用吗? 因为 *pPtr 返回的是一个 Profile<float>&,它应该接受一个subscribe操作符,而这个操作符对于 p[d] 是可接受的。 - Dietmar Kühl
真是太奇怪了!在苦苦挣扎了四个小时并且不断遭遇编译错误之后,现在它居然开始工作了。8^P - J Edward Ellis
@JEdwardEllis:也许你之前尝试过 *pPtr[d] 或者 *(pPtr)[d] - ildjarn
也许你在此期间添加了 Profile<float>::operator[](const ::tm&) - André Caron
显示剩余2条评论
3个回答

2
您展示的代码是正确的;可能在之前的尝试中,您使用了*(pPtr)[d]而不是(*pPtr)[d],这很容易引起错误,因为operator*的优先级低于operator[]

具体来说,我正在执行 *(pPtr)[d]。 - J Edward Ellis

1
你列出的选项很合理。我不明白为什么指针解引用不起作用。以下代码可以成功编译:
std::vector<int> v;
v.push_back(0);
v[0];

std::vector<int>* vp = &v;
(*vp)[0];

是的,现在我的代码也能编译了。我不知道为什么会出现编译器错误C2677。 - J Edward Ellis

0
在类似情况下,我会在类中添加额外的方法,例如 'at'。
templateType & Profile::at(int idx) 
{
    return operator[](idx);
}

所以,代码看起来更好:

f = pPtr->at(i); 

顺便说一下,在类方法(在我们的情况下是Profile)中使用 at(idx)比 operator[](idx) 更简单。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接