C ++:无法从派生类访问受保护的成员

时间:2015-12-02 15:18:17

标签: c++ c++11

我有一个类MyVariable,它包含一个对象,并在必须修改此对象时执行一些额外的工作。现在,我希望将此专门用于MyContainer容器对象,这些容器对象仅在修改容器本身(例如通过push_back())而不是其元素时才执行此额外工作。

我的代码如下所示:

template<typename T>
class MyVariable
{
public:
    //read-only access if fine
    const T* operator->() const {return(&this->_element);}
    const T& operator*()  const {return( this->_element);}

    //write acces via this function
    T& nonconst()
    {
        //...here is some more work intended...
        return(this->_element);
    }
protected:
    T _element;
};


template<typename T>
class MyContainer: public MyVariable<T>
{
public:
    template<typename Arg>
    auto nonconst_at(Arg&& arg) -> decltype(MyVariable<T>::_element.at(arg))
    {
        //here I want to avoid the work from MyVariable<T>::nonconst()
        return(this->_element.at(arg));   
    }
};


#include <vector>
int main()
{
    MyContainer<std::vector<float>> container;
    container.nonconst()={1,3,5,7};
    container.nonconst_at(1)=65;
}

然而,在GCC4.7.2中,我收到一条错误,我无法访问_element因为它受到保护。

test1.cpp: In substitution of 'template<class Arg> decltype (MyVariable<T>::_element.at(arg)) MyContainer::nonconst_at(Arg&&) [with Arg = Arg; T = std::vector<float>] [with Arg = int]':
test1.cpp:39:25:   required from here
test1.cpp:17:4: error: 'std::vector<float> MyVariable<std::vector<float> >::_element' is protected
test1.cpp:26:7: error: within this context
test1.cpp: In member function 'decltype (MyVariable<T>::_element.at(arg)) MyContainer<T>::nonconst_at(Arg&&) [with Arg = int; T = std::vector<float>; decltype (MyVariable<T>::_element.at(arg)) = float&]':
test1.cpp:17:4: error: 'std::vector<float> MyVariable<std::vector<float> >::_element' is protected
test1.cpp:39:25: error: within this context
test1.cpp: In instantiation of 'decltype (MyVariable<T>::_element.at(arg)) MyContainer<T>::nonconst_at(Arg&&) [with Arg = int; T = std::vector<float>; decltype (MyVariable<T>::_element.at(arg)) = float&]':
test1.cpp:39:25:   required from here
test1.cpp:17:4: error: 'std::vector<float> MyVariable<std::vector<float> >::_element' is protected
test1.cpp:26:7: error: within this context

这里发生了什么?

1 个答案:

答案 0 :(得分:3)

问题确实似乎特定于decltype()的使用 - 如果我明确声明nonconst_at()返回T::value_type&,那么:

template<typename Arg>
typename T::value_type& nonconst_at(Arg&& arg)

然后GCC 4.8.2编译它没有警告或错误。对于标准容器来说这很好,但显然对每种情况都没有帮助。

实际上调用this->_element.at(arg)不是问题:我可以省略尾随返回类型并让编译器推断它:

template<typename Arg>
auto& nonconst_at(Arg&& arg)
{
    //here I want to avoid the work from MyVariable<T>::nonconst()
    return this->_element.at(std::forward<Arg>(arg));
}

只有一个警告(随-std=c++1y消失)并且没有错误。我仍然需要this->,因为_element是依赖基类的成员(谢谢,Simple)。

编辑 - 其他解决方法:

由于您只对T::at()的返回值类型感兴趣,您可以使用decltype调用任何您喜欢的T,甚至是空指针:

template<typename Arg>
auto nonconst_at(Arg&& arg) -> decltype(((T*)nullptr)->at(arg))
{
    //here I want to avoid the work from MyVariable<T>::nonconst()
    return this->_element.at(std::forward<Arg>(arg));
}

它很难看,但似乎确实有效。