通用成员函数定义,可以从'const'和& '非const'对象

时间:2014-11-22 21:56:39

标签: c++ c++11 gcc c++14 mingw-w64

有没有办法定义一个可以从'const'和'amp; '非const'对象?

我需要这个列表类的sList实现。在其中我想声明一个函数,该函数将另一个函数作为参数,使用'const'或'non-const'指针指向sList,并为当前sList结构中的每个列表调用它。

这是它的声明:

template <typename T>
struct sList
{
    sList(initializer_list<T>);

    inline void DoForEachList(auto pFunc)
    {
        for(auto p = this; p; p = p->pNext)
            pFunc(p);
    }

    ~sList();

    T dat;

    sList *pNext = nullptr;
};

我正在使用auto pFunc因为我想最终传递lambdas。所以现在如果我有一个这种类型的const对象并从它调用'DoForEachList'作为参数传递lambda函数,其中1个arg来自类型'auto'。我的编译器将失败,例如:

  

错误:将const sList<unsigned char>作为this的{​​{1}}参数传递[void sList<T>::DoForEachList(auto:1) = auto:1; main()::<lambda(sList<unsigned char>*)> = T]'丢弃限定符[-fpermissive]

代码调用unsigned char

DoForEachList

我是否可以通过某种方式定义void main() { extern const sList<unsigned char> cvobj; cvobj.DoForEachList([] (auto pCurr) {/* Do something */}); } 成员函数(或成员函数模板),如下所示:

DoForEachList

2 个答案:

答案 0 :(得分:6)

在评论中建立@dyp的答案:

如果要在this的常量上重载,确实需要两个单独的函数。但是,您可以通过将工作卸载到辅助函数来最小化重复。

@dyp建议使用友元函数模板,但朋友函数没有访问控制,所以我通常更喜欢静态成员函数;然后,您可以将其设为私有或受保护:

template <typename T>
struct sList
{
    void DoForEachList(auto pFunc)
    {
        DoForEachListHelper(*this, pFunc);
    }
    void DoForEachList(auto pFunc) const
    {
        DoForEachListHelper(*this, pFunc);
    }
private:
    static void DoForEachListHelper(auto&& self, auto pFunc)
    {
        for(auto p = &self; p; p = pNext->pNext)
            pFunc(p);
    }
};

答案 1 :(得分:0)

您应该只使用const成员函数并创建成员变量mutable,它告诉编译器/您该成员不会影响&#34;已被更改&#34 ;班级的行为。如果不是这种情况,请重新考虑您的设计,因为这不太对。 mutable更正确,例如地图的密钥需要修改,以免影响该地图的排序,但即便如此......

代码示例:

struct Bla
{
    void increment() const { i++; }
private:
    mutable int i = 0;
};

int main()
{
    const Bla bla;
    bla.increment();
}

Live demo here