C++ 包装类常量正确性问题
我试图围绕JsonCpp的C++ 包装类常量正确性问题,c++,c++11,constants,wrapper,const-correctness,C++,C++11,Constants,Wrapper,Const Correctness,我试图围绕JsonCpp的Json::Value创建一个包装器 我有一个名称空间global,其中有处理Json::Value&参数的函数。我想为这些函数创建一个更符合语法的包装类 这是一个最小的例子 // Impl is a typedef for Json::Value, from JsonCpp namespace global { Impl& getChild(Impl& mImpl, const std::string& mName) { return
Json::Value
创建一个包装器
我有一个名称空间global
,其中有处理Json::Value&
参数的函数。我想为这些函数创建一个更符合语法的包装类
这是一个最小的例子
// Impl is a typedef for Json::Value, from JsonCpp
namespace global
{
Impl& getChild(Impl& mImpl, const std::string& mName) { return mImpl[mName]; }
const Impl& getChildConst(const Impl& mImpl, const std::string& mName) { return mImpl[mName]; }
Impl::iterator beginNonConst(Impl& mRoot) { return mRoot.begin(); }
Impl::iterator endNonConst(Impl& mRoot) { return mRoot.end(); }
Impl::const_iterator beginConst(const Impl& mRoot) { return mRoot.begin(); }
Impl::const_iterator endConst(const Impl& mRoot) { return mRoot.end(); }
}
class Wrapper
{
private:
Impl& impl;
public:
Wrapper(Impl& mImpl) : impl(mImpl) { }
Wrapper operator[](const std::string& mName) { return global::getChild(impl, mName); }
// Error here
// no known conversion for argument 1 from 'const Impl {aka const Json::Value}' to 'Impl& {aka Json::Value&}'
const Wrapper operator[](const std::string& mName) const { return global::getChildConst(impl, mName); }
Impl::iterator begin() { return global::beginNonConst(impl); }
Impl::iterator end() { return global::endNonConst(impl); }
Impl::const_iterator begin() const { return global::beginConst(impl); }
Impl::const_iterator end() const { return global::endConst(impl); }
};
这就是我希望能够编译的内容:
int main()
{
Json::Value realValue;
Wrapper w(realValue)
for(const auto& i : w["numberArray"]) { cout << i << endl; }
for(auto& i : w["numberArray"]) { i += 100; }
// assert that changes have been made to realValue through the wrapper
return 0;
}
intmain()
{
Json::Value realValue;
包装器w(真实值)
对于(const auto&i:w[“numberArray”]){cout两个运算符[]的返回类型是否都错了?它应该分别为Impl和/const Impl&?AWrapper
有一个类型为Impl和的成员。使Wrapper
对象const
只会更改其成员的顶级const
(这对引用不起任何作用,引用已经不可重新绑定),甚至只有在构造函数完成后才生效
您需要一个具有类型为const Impl&
的成员的类,而const Wrapper
不需要。编译器正确地防止您丢失const
限定符,并将const Impl&
传递给Wrapper::Wrapper(Impl&)
,这可能会改变其参数
一般来说,const\u迭代器
与iterator
是一个独立的类。我看不出你的包装器
有什么不同
作为一个短期解决方案,您可以使用
const Wrapper operator[](const std::string& mName) const { return global::getChild(impl, mName); }
但这并不能阻止任何人将返回值复制到非常量包装器
对象中,并使用它来变异Impl
不一定。看起来OP依赖于对包装器的隐式转换。嘿,我在Zack的评论后捕捉到了它,但同时你正在编写答案:)