I am trying to create a thin wrapper around some parsing libraries (JSON, YAML, etc.) which will allow me to use a unified syntax regardless of the file-type/parser I am using. I want the wrapper to leverage templating so I don't have to do any dynamic checks at runtime to check which library I am using (this is a partly academic pursuit).
The important part of the wrapper structure is here:
template<typename K> struct Wrapper
{
K node; // Element that is wrapped
Wrapper() {};
Wrapper(K impl) : node(impl) {};
Wrapper(const Wrapper<K>& other) : node(other.node) {};
const Wrapper<K> operator[](const char* key);
//... Other stuff
}
My problem is that I am experiencing compile time errors when I attempt to chain multiple []
operations together.
The operator[]
overload can be found here:
// Returning by value since I am creating an object that goes out of scope.
// This is okay because the parsing is read only.
template<> const Wrapper<to_wrap> Wrapper<to_wrap>::operator[](const char* key)
{
// It is safe to assume that node[key] produces a to_wrap type.
return Wrapper<to_wrap>(node[key]);
}
With some examples of how it would be called:
template<typename T> bool configure(T config)
{
Wrapper<T> root(config);
// Method A
Wrapper<T> thing = root["field1"]["field2"];
// Method B
Wrapper<T> first_thing = root["field1"];
Wrapper<T> second_thing = first_thing["field2"];
}
The compile-time error occurs if I attempt Method A
. Method B
yields the result I expect at compile and run-time: a Wrapper
object that contains the appropriate node
. The error from A
is below:
error: conversion from ‘const char’ to non-scalar type ‘Wrapper<to_wrap>’ requested Wrapper<T> thing = root["field1"]["field2"];
This leads me to think there is an issue with how the compiler is inferring type, but I am not entirely sure. Any help/insights would be greatly appreciated!
CodePudding user response:
Change
const Wrapper<K> operator[](const char* key);
to
const Wrapper<K> operator[](const char* key) const;
or - better still - make const and non-const versions of operator[]
.
Wrapper<K> operator[](const char* key);
const Wrapper<K> operator[](const char* key) const;
Your current operator[]
returns a const
object, and is not permitted to be used on const
objects.