我有一个类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
这里发生了什么?
答案 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));
}
它很难看,但似乎确实有效。