首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类,该类将转换为索引和指针并引用容器

类,该类将转换为索引和指针并引用容器
EN

Stack Overflow用户
提问于 2016-11-07 16:26:32
回答 1查看 27关注 0票数 0

我尝试编写一个通过索引访问容器中的元素的类。因此,我将能够重新路由指向的容器(但这对于我当前的问题并不重要)。它将帮助我摆脱复杂的复制构造函数。

这个类应该表现为一个数字(即索引)和一个指针(即它所指向的指针)。因此,我有转换。然而,我得到了编译器错误:

代码语言:javascript
复制
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)>语法,是否会导致上述错误?

这是我的代码:

代码语言:javascript
复制
#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;
}
EN

回答 1

Stack Overflow用户

发布于 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_tuplemake_pair的模板化助手函数make_paxref来进行类型推导,从而解决这个问题。或者,您可以等待C++17,其中模板参数推导也适用于模板化类的构造函数:)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40460715

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档