Home > OS >  Compile fails for chained overloaded subscript operator[]
Compile fails for chained overloaded subscript operator[]

Time:12-10

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.

  • Related