我尝试编写一个通过索引访问容器中的元素的类。因此,我将能够重新路由指向的容器(但这对于我当前的问题并不重要)。它将帮助我摆脱复杂的复制构造函数。
这个类应该表现为一个数字(即索引)和一个指针(即它所指向的指针)。因此,我有转换。然而,我得到了编译器错误:
In instantiation of 'class paxRef<Dog&, std::vector<Dog> >':
34:47: required from here
13:5: error: forming pointer to reference type 'Dog&'
In function 'int main()':
37:7: error: base operand of '->' has non-pointer type 'paxRef<Dog&, std::vector<Dog> >'
38:7: error: base operand of '->' has non-pointer type 'paxRef<Dog&, std::vector<Dog> >'
44:43: error: base operand of '->' has non-pointer type 'paxRef<Dog&, std::vector<Dog> >'
45:43: error: base operand of '->' has non-pointer type 'paxRef<Dog&, std::vector<Dog> >'forming pointer to reference type 'Dog&'是什么意思?如果我有一个隐式的指针转换,我真的需要定义一个->操作符吗?是否有可能缩短paxRef<decltype(v.back()), decltype(v)>语法,是否会导致上述错误?
这是我的代码:
#include <iostream>
#include <string>
#include <vector>
template <class T, class C>
class paxRef
{
public:
paxRef(size_t index, C* container) : _index(index), _container(container) { }
//implicit conversion
operator size_t() const { return _index; }
operator T*() { return &(_container->at(_index)); }
//operator ->() { return T*(); } // Do I need to define the -> operator if I already have a pointer-conversion operator?
private:
size_t _index;
C* _container;
};
class Dog
{
public:
std::string bark() { return _sound; }
void setName(std::string sound) { _sound=sound; }
private:
std::string _sound = "Wuff";
};
int main()
{
std::vector<Dog> v(5);
paxRef<decltype(v.back()), decltype(v)> r2(2, &v); // Very verbos.
paxRef<decltype(v.back()), decltype(v)> r4(4, &v); // Can I drop the < ... > part somehow?
r2->setName("Bello");
r4->setName("Fatty");
for(size_t i{ 0 }; i<v.size(); ++i)
std::cout<<"Dog at "<<i<<" says "<<v.at(i).bark()<<std::endl;
std::cout<<std::endl;
std::cout<<"ref at "<<r2<<" says "<<r2->bark()<<std::endl;
std::cout<<"ref at "<<r4<<" says "<<r4->bark()<<std::endl;
}发布于 2016-11-07 17:02:58
是的,你需要显式定义operator->,即使你有一个隐式的指针转换。
标准声明在over.match.oper/2中
如果任一操作数的类型是类或枚举,则可以声明实现此运算符的用户定义运算符函数,或者需要使用用户定义的转换将该操作数转换为适用于内置运算符的类型。在这种情况下,重载解析用于确定要调用哪个运算符函数或内置运算符来实现运算符。..。
然后在over.match.oper/3中描述重载解决方案,本例的相关部分是over.match.oper/3.3:
对于
operator,、一元operator &或operator ->,内置候选项集为空。..。
这意味着不会考虑允许调用内置operator-> (在本例中为Dog*)的任何转换,并且您的类必须有operator->的成员或非成员定义。
关于模板参数的显式注释:您可以通过定义一个类似于make_tuple或make_pair的模板化助手函数make_paxref来进行类型推导,从而解决这个问题。或者,您可以等待C++17,其中模板参数推导也适用于模板化类的构造函数:)
https://stackoverflow.com/questions/40460715
复制相似问题