使用模板和指针重载数组运算符
以下代码在 clang++-2.9 和 g++-4.6 上编译(没有警告)。但是,g++ 二进制文件出现段错误,而 clang++ 二进制文件按预期运行。
重载 [] 时通过指针访问模板类数据成员的正确方法是什么?
这是代码:
#include <iostream>
template <typename T>
class A {
private:
T val1;
T val2;
public:
T& getVal1() { return val1; }
void setVal1(T aVal) { val1 = aVal; }
T& getVal2() { return val2; }
void setVal2(T aVal) { val2 = aVal; }
};
template <typename T>
class B {
private:
A<T>* aPtr;
public:
A<T>* getAPtr() { return aPtr; }
T& operator[](const int& key) {
if(key == 0) { T& res = getAPtr()->getVal1();
return res; }
else { T& res = getAPtr()->getVal2();
return res; }
}
};
int main()
{
B<int> foo;
foo[0] = 1;
int x = foo[0];
std::cout << foo[0] << " " << x << std::endl; // 1 1
}
The following code compiles (without warnings) on both clang++-2.9 and g++-4.6. However, the g++ binary Seg Faults, while the clang++ binary runs as intended.
What is the proper way to access template class data members through pointers when overloading []?
Here's the code:
#include <iostream>
template <typename T>
class A {
private:
T val1;
T val2;
public:
T& getVal1() { return val1; }
void setVal1(T aVal) { val1 = aVal; }
T& getVal2() { return val2; }
void setVal2(T aVal) { val2 = aVal; }
};
template <typename T>
class B {
private:
A<T>* aPtr;
public:
A<T>* getAPtr() { return aPtr; }
T& operator[](const int& key) {
if(key == 0) { T& res = getAPtr()->getVal1();
return res; }
else { T& res = getAPtr()->getVal2();
return res; }
}
};
int main()
{
B<int> foo;
foo[0] = 1;
int x = foo[0];
std::cout << foo[0] << " " << x << std::endl; // 1 1
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在返回对局部变量 (res) 的引用。从操作符[]返回后,引用将无效。它可能会被其他东西覆盖。真正发生的是未定义:这就是为什么编译器被允许吃掉你的孩子或长胡子:未定义的行为
你可能想按值返回。
编辑
由于您有设置器,因此不需要参考:请在http://ideone.com/oxslQ
注意:还有一个问题是
aPtr
未初始化。我为此提出了一个简单的构造函数。 _您可能想从其他地方初始化它或者您需要。
You are returning a reference to a local variable (res). The reference won't be valid after returning from operator[]. It could be overwritten by other stuff. What really happens is Undefined: that is why compilers are allowed to eat your children or grow a moustache: Undefined Behaviour
You probably want to return by value.
Edit
Since you have a setter, you don't need the reference: See the solution live at http://ideone.com/oxslQ
Note: there was another problem with
aPtr
not being initialized. I proposed a simple constructor for that. _You might want to initialize this from elsewhere OR you need.
如果你想通过 ref 返回,那么你的 A::getValX() 函数也应该通过 ref 返回,并且 B::operator 中的
res
变量也应该是 T& 。而不是 T:(请注意,它仍然会在运行时崩溃,因为 aPtr 未在任何地方初始化。)
您的原始代码返回对局部变量 res 的引用,而不是您可能想要的 A::val1 / A::val2 。如果 res 是非引用变量,那么它将是 val1 / val2 值的简单副本,仅在声明它的范围(在本例中为函数)内有效。所以你需要一个参考。
If you want to return by ref, then your A::getValX() functions should also return by ref, and your
res
variable inside B::operator should also be T& instead of T:(Note that it will still crash at runtime, since aPtr isn't initialized anywhere.)
Your original code returns a reference to the local variable res, not to A::val1 / A::val2 as you probably intended. If res is a non-reference variable, then it will be a simple copy of the val1 / val2 value, that is only valid for inside the scope (in this case the function) where it was declared. So you need a reference here.